React+AntDesign做一个日历,Calendar自定义headerRender

话不多说,直接贴效果图😄
在这里插入图片描述

日历是用的AntDesign提供的Calendar组件,这个组件还是蛮强大的,可以自定义头部时间下拉;渲染每个时间段,或者重置时间段内容,玩的空间是很大的

直接贴代码

第一步:下载js-calendar-converter添加到项目中,用于获取节假日等信息,如果需求没要求 可以不用这个,并将代码中关乎它的相关代码去掉即可

yarn add  js-calendar-converter

第二步:页面开发代码如下

import React, { PureComponent } from 'react';
import { Calendar, message, Icon } from 'antd';
import { Moment } from 'moment';
import moment from 'moment';
// @ts-ignore
import calendar from 'js-calendar-converter';
import './index.less';

export interface MarketingCalendarPageSettingStates {
    /**
     * 开始渲染日历(在改变updateLocale之后渲染,周日才会展示在前面)
     */
    isStartLoadingCalendar: boolean;
    /**
     * 目前的时间
     */
    value: Moment;
}

export class MarketingCalendarPageSetting extends PureComponent<
    any,
    MarketingCalendarPageSettingStates
> {
    constructor(props: any) {
        super(props);
        this.state = {
            isStartLoadingCalendar: false,
            value: moment(),
        };
    }

    componentDidMount() {
        moment.updateLocale('zh-cn', { week: { dow: 0 } });
        this.setState({
            isStartLoadingCalendar: true,
        });
    }

    componentWillUnmount() {
        moment.updateLocale('zh-cn', { week: { dow: 1 } });
    }

    getListData = (value: Moment) => {
        let listData;
        switch (value.date()) {
            case 8:
                listData = [
                    { type: 'warning', content: '内容1' },
                    { type: 'success', content: '内容2' },
                ];
                break;
            case 10:
                listData = [
                    { type: 'warning', content: '内容1' },
                    { type: 'success', content: '内容2' },
                ];
                break;
            case 15:
                listData = [
                    { type: 'warning', content: '内容1' },
                    { type: 'success', content: '内容2' },
                ];
                break;
            default:
        }
        return listData || [];
    };

    onChangeDate = (date?: Moment) => {
        if (date) {
            message.success('改变后的时间' + date);
        }
    };

    headerRender = (value: Moment, onChange: any) => {
        let currentYear = value.format('YYYY年');
        let currentMonth = value.format('M月');
        const next = () => {
            let newMonth = moment(value).add(1, 'months');
            this.setState({
                value: newMonth,
            });
        };
        const prev = () => {
            let prevMonth = moment(value).subtract(1, 'months');
            this.setState({
                value: prevMonth,
            });
        };
        return (
            <div style={{ display: 'flex', justifyContent: 'center' }}>
                <div onClick={prev}>
                    <Icon type="left" theme="outlined" />
                </div>
                <div className="title-text">
                    <span>{currentYear} </span>
                    <span>{currentMonth}</span>
                </div>
                <div onClick={next}>
                    <Icon type="right" theme="outlined" />
                </div>
                <div style={{marginLeft: '50px'}} onClick={this.toToday}>回到今日</div>
            </div>
        );
    };

    toToday = () => {
        this.setState({
            value: moment(),
        });
    };

    // onPanelChange = (value: Moment) => {
    //     message.success('密码改变后的时间22222' + value);
    //     this.setState({ value });
    // };

    render() {
        const { isStartLoadingCalendar, value } = this.state;
        if (!isStartLoadingCalendar) {
            return null;
        }
        const dateCellRender = (value: Moment) => {
            const listData = this.getListData(value); //活动
            const month = value.month() + 1;
            const info: any = calendar.solar2lunar(value.year(), month, value.date()); //当天信息(比如是否是节假日)
            return (
                <div className="marketing-calendar-page-setting__calendar-date">
                    <div className="marketing-calendar-page-setting__calendar-date__tag">
                        {info && info.Term && <span>{info.Term}</span>}
                        {info && info.festival && <span>{info.festival}</span>}
                        {info && info.lunarFestival && <span>{info.lunarFestival}</span>}
                    </div>
                    {listData.map((item: any) => {
                        return <div key={item.content}>{item.content}</div>;
                    })}
                </div>
            );
        };
        return (
            <div className="marketing-calendar-page-setting">
                <div className="marketing-calendar-page-setting__center">
                    <div className="marketing-calendar-page-setting__center__left">
                        <Calendar
                            value={value}
                            headerRender={({ value, onChange }) =>
                                this.headerRender(value, onChange)
                            }
                            // onPanelChange={(value)=>{
                            //     if(value){
                            //         this.onPanelChange(value);
                            //     }
                            // }}
                            locale={moment}
                            dateCellRender={dateCellRender}
                            onChange={this.onChangeDate}
                        />
                    </div>
                    <div className="marketing-calendar-page-setting__center__right"></div>
                </div>
            </div>
        );
    }
}

😄样式我贴一下吧,其实日历中的都可以自定义样式,希望对大家有帮助

.marketing-calendar-page-setting{
  &__center{
    display: flex;
    flex-direction: row;
    &__left{
      width: 770px;
    }
  }

  //以下是日历组件样式
  &__calendar-date {
    margin: 0;
    padding: 0;
    list-style: none;
    .ant-fullcalendar-date{
      position: relative;
    }
    &__tag{
      position: absolute;
      top: 8px;
      right: 5px;
      color: #f4b443;
    }
  }
  .ant-fullcalendar-tbody{
    border-right: 1px solid #e3e3e3;
    border-bottom: 1px solid #e3e3e3;
  }
  .notes-month {
    font-size: 28px;
    text-align: center;
  }
  .notes-month section {
    font-size: 28px;
  }
  .ant-fullcalendar-fullscreen .ant-fullcalendar-value {
    text-align: left;
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值