antd日历控件实现一年日历

2,139 阅读1分钟

版本"antd": "^4.7.0" 实现思路:通过遍历渲染出12个月的日历。需要注意的点:①区分两个api,dateCellRender 追加到单元格 dateFullCellRender 覆盖单元格 ②增加validRange配置,否则非当月日期即使不渲染,点击空白处仍会触发选中事件,尝试过disabledDate没有达到预期效果 ③自定义单元格下拉菜单出不来、绑定事件不触发,需要通过样式控制层级来解决。

import React, { useState, useEffect } from 'react';
import { Calendar, Dropdown, Menu, Row, Col } from 'antd';
import moment from 'moment';
import './index.less';

const FullYearPage = (props) => {
  const arr = ['01 ', '02 ', '03 ', '04 ', '05 ', '06 ', '07 ', '08 ', '09 ', '10 ', '11 ', '12 '];
    const [currentDate, setCurrentDate] = useState('');

  const menu = (
    <Menu onClick={onClick}>
      <Menu.Item key={'delete'}>删除</Menu.Item>
    </Menu>
  );

  const dateFullCellRender = (value, item) => {
    const panelDate = value.format('YYYY-MM-DD');
    const currentDate = value.valueOf();
    const startDate = moment(`2021-${item}`)
      .startOf('month')
      .valueOf(); //当月第一天
    const endDate = moment(`2021-${item}`)
      .endOf('month')
      .valueOf(); //当月最后一天
    // 取当前月第一天和最后一天的时间戳,在这个区间内说明是当前月的日期,其他多余的日期不渲染
    // Dropdown下拉菜单出不来 绑定的事件不触发 解决方案:控制样式,增加层级
    return currentDate >= startDate && currentDate <= endDate ? (
      <Dropdown overlay={menu} trigger={['contextMenu']}>
        <div className="custom-cell"  onContextMenu={() => setCurrentDate(panelDate)}>
          <div>{panelDate.slice(-2)}</div>
        </div>
      </Dropdown>
    ) : null;
  };

  return (
    <div className="holiday-page">
      <Row gutter={20}>
        {arr.map((item) => {
          const startDate = moment(`2021-${item}`).startOf('month');
          const endDate = moment(`2021-${item}`).endOf('month');
          return (
            <Col span={6} key={item}>
              <Calendar
                headerRender={() => <div className="custom-header">{item + '月'}</div>}
                dateFullCellRender={(value) => dateFullCellRender(value, item)}
                fullscreen={false}
                defaultValue={moment(`2021-${item}`)}
                // 在dateFullCellRender方法里面只渲染了当前月的日期,
                // 但是点击其他非本月日期的空白处仍会触发选中事件,
                // 所以增加了validRange配置,该配置的值是个区间,当前月的开始日期和结束日期。
                validRange={[startDate, endDate]}
              />
            </Col>
          );
        })}
      </Row>
    </div>
  );
};

export default FullYearPage;

完。