这是 CalendarDate.js

import React, { useState, useEffect, useRef } from 'react'import { Icon } from 'antd'import './CalendarMore.css'import './CalendarDate.css'import { getMonth, weekArr } from './canlendarConfig'import moment from 'moment'function CalendarDate(props) {    console.log('props', props);    const [selectedValue, setSelectedValue] = useState([])//选中的值    const [canSelectedList, setCanSelectedList] = useState([])//可选数组    const [isShow, setIsShow] = useState(true)//日历组件是否显示    const { list = [], onChange, } = props    const calendarDiv = useRef(null);    //设计默认值    useEffect(() => {        setSelectedValue(props.value || [])        setCanSelectedList(list.map(one => one.code))        document.addEventListener('click', outDivClickHandler);        return () => {            document.removeEventListener('click', outDivClickHandler);        }    }, [])    function setSelectedValueChange(value) {        setSelectedValue(value)        onChange && onChange(value)    }    function outDivClickHandler(e) {        let result = (calendarDiv.current).contains(e.target);        if (!result) {            setIsShow(false)        }    }    return (        <div ref={calendarDiv}>            <div className='calendar-more' >                <div className='show-box'  >                    <div className='selected-show'>                        {selectedValue.length > 0 ? selectedValue.map(one => <div key={one} className='selected-item days-width'>                            {one}                            <Icon type="close" style={{fontSize:'12px', cursor:'pointer'}} onClick={() => setSelectedValueChange(selectedValue.filter(item => item != one))} />                        </div>) : <span style={{ color: 'rgba(0, 0, 0, 0.30)' }}>请抉择日期</span>}                    </div>                    <div className='icon-calendar' onClick={() => setIsShow(!isShow)}><Icon type="calendar" /></div>                </div>            </div>            {isShow ? <CalendarDays                canSelectedList={canSelectedList}                selectedValue={selectedValue}                setSelectedValue={setSelectedValueChange}            /> : null}        </div>    )}function CalendarDays(props) {    const nowDate = moment().format('YYYY-M').split('-')    const [yearNumber, setYearNumber] = useState(nowDate[0])    const [monthNumber, setMonthNumber] = useState(nowDate[1])    const { selectedValue = [], canSelectedList = [], setSelectedValue } = props    console.log('canSelectedList', canSelectedList)    function changeDays(value, isSelected) {        if (isSelected) {            setSelectedValue(selectedValue.filter(one => one != value))        } else {            setSelectedValue([...selectedValue, value])        }    }    const daysList = getMonth(yearNumber, monthNumber)    function changAddNumber() {        let number = Number(monthNumber) + 1        if (number == 13) {            number = 1            setYearNumber(Number(yearNumber) + 1)        }        setMonthNumber(number)    }    function changLessMonth() {        let number = Number(monthNumber) - 1        if (number == 0) {            number = 12            setYearNumber(Number(yearNumber) - 1)        }        setMonthNumber(number)    }    return <div className='calendar-days'>        <div className='calendar-title'>            <div><Icon type="double-left" onClick={() => setYearNumber((Number(yearNumber) - 1))} /></div>            <div><Icon type="left" onClick={changLessMonth} /></div>            <div className='year-number'>{yearNumber}年{monthNumber}月</div>            <div><Icon type="right" onClick={changAddNumber} /></div>            <div><Icon type="double-right" onClick={() => setYearNumber(Number(yearNumber) + 1)} /></div>        </div>        <div className='calendar-days-content'>            {weekArr.map(one => <div className='other-days' key={`week-${one}`}>{one}</div>)}            {daysList.map(one => {                const nowValue = moment(one.date).format('YYYYMMDD')                const isSelected = selectedValue.includes(nowValue)                return <div                    onClick={() => changeDays(nowValue, isSelected)}                    className={`common-days ${one.type == 'now' ? 'now-days' : 'other-days'} ${isSelected ? ' common-days-active' : ''}`}                    key={`${one.type}-${one.value}`}>                    {one.value}                </div>            })}        </div>    </div>}export default CalendarDate

这是CalenDarDate.css

.calendar-days{  position: absolute;  border: 1px solid rgba(0, 0, 0, 0.15) ;}.calendar-days-content{  display: flex;  flex-wrap: wrap;}.other-days,.now-days{  width:calc(100% / 7);  text-align: center;}.other-days{  color: #999;}.now-days{  color: #000;}.common-days-active{  background-color: #7300FF;  color:#fff;}.common-days:hover{  background-color: #efe6f5;}.days-width{  min-width: 86px;}

这是calendarConfig.js

import moment from 'moment'export const weekArr = ['一', '二', '三', '四', '五', '六', '七']export const getMonth = (year, month) => {    const date = `${year}-${month}`    const lastArr = getLastDays(date)    const nowMonthDays = moment(date).endOf('month').format('YYYY-MM-DD').split('-')[2]    const size = 42 - nowMonthDays - lastArr.length    let nextStr = moment(date).add(1, 'month').format('YYYY-MM')    const nowArr = getDays(nowMonthDays, 'now', date)    const nextArr = getDays(size, 'next', nextStr)    console.log('data', date, lastArr, nowMonthDays, nextArr, nextStr);    return [...lastArr, ...nowArr, ...nextArr]}//获取上个月的日期参数const getLastDays = (date) => {    const start = moment(date).startOf('week').format('YYYY-MM-DD')    const end = moment(start).endOf('month').format('YYYY-MM-DD')    console.log('start', start, end, date);    if (start == moment(date).format('YYYY-MM-DD')) {        return []    }    return getDateArr(start, end)}//获取size长度的数组const getDays = (size, type, str) => {    const data = []    for (let i = 0; i < size; i++) {        data.push({ value: i + 1, type: type, date: `${str}-${i + 1}` })    }    return data}//获取上个月的数组const getDateArr = (start, end) => {    const min = start.split('-')    let str = `${min[0]}-${min[1]}`    const max = end.split('-')[2]    let data = []    console.log('min',min, max);    for (let i = 0; i < max - min[2]; i++) {        const value = Number(min[2]) + i + 1        data.push({ value: value, type: 'last', date: `${str}-${value}` })    }    return data}// const adasd = {//     "name": "@param_age",//     "title": "年龄",//     "stype": 0,//     "values": [//         {//             "name": "19-24岁",//             "code": "5"//         }, {//             "name": "25-29岁",//             "code": "1"//         }//     ]// }// function getAgeValue(data = {}) {//     let { values = [] } = data//     console.log("getAgeValue -> values", values)//     let str = ''//     if (values.length > 0) {//         const firstValue = values[0].name.split('-')//         let start = firstValue[0]//         let end = firstValue[1].replace('岁', '')//         if (values.length > 1) {//             const endValue = values[values.length - 1].name.split('-')//             end = endValue[1].replace('岁', '')//         }//         str = `${start}-${end}`//     }//     return str// }

这是CalendarMore.js

import React, { useState, useEffect, useRef } from 'react'import { Icon } from 'antd'import moment from 'moment'import './CalendarMore.css'function CalendarMore(props) {    const [selectedValue, setSelectedValue] = useState([])//选中的值    const [canSelectedList, setCanSelectedList] = useState([])//可选数组    const [isShow, setIsShow] = useState(false)//日历组件是否显示    const { list = [], onChange } = props    const calendarDiv = useRef(null);    //设计默认值    useEffect(() => {        setSelectedValue(props.value || [])        setCanSelectedList(list.map(one => one.code))        document.addEventListener('click', outDivClickHandler);        return () => {            document.removeEventListener('click', outDivClickHandler);        }    }, [])    function setSelectedValueChange(value) {        setSelectedValue(value)        onChange && onChange(value)    }    function outDivClickHandler(e) {        let result = (calendarDiv.current).contains(e.target);        if (!result) {            setIsShow(false)        }    }    return (        <div ref={calendarDiv}>            <div className='calendar-more' >                <div className='show-box'  >                    <div className='selected-show'>                        {selectedValue.length > 0 ? selectedValue.map(one => <div key={one} className='selected-item'>                            {one}                            <Icon type="close" onClick={() => setSelectedValueChange(selectedValue.filter(item => item != one))} />                        </div>) : <span style={{ color: 'rgba(0, 0, 0, 0.30)' }}>请抉择日期</span>}                    </div>                    <div className='icon-calendar' onClick={() => setIsShow(!isShow)}><Icon type="calendar" /></div>                </div>            </div>            {isShow ? <CalendarMonth                canSelectedList={canSelectedList}                selectedValue={selectedValue}                setSelectedValue={setSelectedValueChange}            /> : null}        </div>    )}function CalendarMonth(props) {    const [yearNumber, setYearNumber] = useState(moment().year())    const { selectedValue = [], canSelectedList = [], setSelectedValue } = props    const monthArr = [        { name: 1, value: '01' },        { name: 2, value: '02' },        { name: 3, value: '03' },        { name: 4, value: '04' },        { name: 5, value: '05' },        { name: 6, value: '06' },        { name: 7, value: '07' },        { name: 8, value: '08' },        { name: 9, value: '09' },        { name: 10, value: '10' },        { name: 11, value: '11' },        { name: 12, value: '12' },    ]    function selectedMonth(value, isSelected) {        if (isSelected) {            setSelectedValue(selectedValue.filter(one => one != value))        } else {            setSelectedValue([...selectedValue, value])        }    }    return <div className='calendar-month'>        <div className='calendar-content'>            <div className='calendar-title'>                <div><Icon type="double-left" onClick={() => setYearNumber(yearNumber - 1)} /></div>                <div className='year-number'>{yearNumber}年</div>                <div><Icon type="double-right" onClick={() => setYearNumber(yearNumber + 1)} /></div>            </div>            <div className='month-show'>                {monthArr.map(one => {                    const value = `${yearNumber}${one.value}`                    const isCanSelected = canSelectedList.includes(value)                    const isSelected = selectedValue.includes(value)                    return isCanSelected ? <div key={one.name} className={`month-box ${isSelected ? ' month-box-active' : ''}`} onClick={() => selectedMonth(value, isSelected)}>{one.name}月</div>                        : <div key={one.name} className=' month-box month-box-disable'>{one.name}月</div>                })}            </div>        </div>    </div>}export default CalendarMore

这是CalendarMore.css

.calendar-more{  border:1px solid #DADADA;  height: 30px;  -webkit-box-sizing: border-box;  box-sizing: border-box;  margin: 0;  padding: 0;  font-variant: tabular-nums;  list-style: none;  -webkit-font-feature-settings: 'tnum';  font-feature-settings: 'tnum', "tnum";  position: relative;  display: inline-block;  width:100%;  height: 32px;  padding: 4px 11px;  color: rgba(0, 0, 0, 0.65);  font-size: 14px;  line-height: 1.5;  background-color: #fff;  background-image: none;  border: 1px solid #d9d9d9;  border-radius: 4px;  -webkit-transition: all 0.3s;  transition: all 0.3s;}.show-box{  display: flex;  width: 100%;  justify-content: space-between;}.selected-show{  width: calc(100% - 30px);  display: flex;  overflow-x: auto;}.icon-calendar{  width: 20px;}.calendar-month{  position: relative;}.calendar-content{  position: fixed;  z-index: 99999;  width:300px;  height:205px;  background:rgba(255,255,255,1);  box-shadow:0px 0px 6px 0px rgba(0,0,0,0.15);  border-radius:3px;}.year-number{  font-size:12px;  font-family:SourceHanSansCN-Regular,SourceHanSansCN;  font-weight:400;  color:rgba(40,40,40,0.85);}.calendar-title{  font-size:12px;  font-family:SourceHanSansCN-Regular,SourceHanSansCN;  display: flex;  height: 36px;  justify-content: space-between;  border-bottom: 1px solid rgba(0, 0, 0, 0.15) ;  padding: 0px 10px;}.month-show{  display: flex;  flex-wrap: wrap;  justify-content: space-around;  font-size: 12px;}.selected-show::-webkit-scrollbar {  width: 3px;  height: 3px;}/* Track */.selected-show::-webkit-scrollbar-track {  -webkit-box-shadow: none;  border-radius: 0;  background-color: transparent;}/* Handle */.selected-show::-webkit-scrollbar-thumb {  width: 2px !important;  height: 6px !important;  border-radius: 4px;  background: rgba(111, 33, 212, 0.8);  -webkit-box-shadow: inset 0 0 6px rgba(103, 82, 197, 0.3);}.selected-item{  background: #F5f5f5;  display: flex;  align-items: center;  color: #000;  padding: 2px 5px;  font-size: 12px;  margin:0px 2px;  min-width: 50px;}.month-box{  width: 32px;  height: 32px;  margin: 5px calc((100% - 32*3px) /6);  text-align: center;  border-radius: 50%;  line-height: 32px;  -webkit-transition: all 0.3s;  transition: all 0.3s;}.month-box:hover{  background-color: #efe6f5;}.month-box-active{  background-color: #7300FF;  color:#fff;}.month-box-disable{  cursor:not-allowed;  background-color: #ccc;}.month-box-disable:hover{  cursor:not-allowed;  background-color: #ccc;}

这是index.js

import React, { useEffect, useState } from 'react'import { Form, Button, Input } from 'antd'import CalendarMore from './CalendarMore'import CalendarDate from './CalendarDate'const data = [    {        "code": "202002",        "name": "202002"    },    {        "code": "201902",        "name": "201902"    },    {        "code": "202003",        "name": "202003"    },    {        "code": "201905",        "name": "201905"    },    {        "code": "201803",        "name": "201803"    },    {        "code": "202005",        "name": "202005"    }]function TestForm(props) {    const [date, setDate] = useState([])    function submit(e) {        e.preventDefault();        props.form.validateFields((err, values) => {            if (!err) {                console.log('Received values of form: ', values);            }        });    }    useEffect(() => {        setTimeout(() => {            yarn(["202003", "202002"])        }, 2000);    }, [])    const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = props.form;    return (        <div>            <Form>                {/* <Form.Item style={{ width: 300 }}>                    {getFieldDecorator('@param_month', {                        initialValue: date,                        rules: [{ required: true, message: 'Please input your Password!' }],                    })(                        <CalendarMore list={data} key={JSON.stringify(date)} />                    )}                </Form.Item> */}                <Form.Item style={{ width: 300 }}>                    {getFieldDecorator('@param_month23', {                        initialValue: ["20200322", "20200212"],                        rules: [{ required: true, message: 'Please input your Password!' }],                    })(                        <CalendarDate list={data} key={JSON.stringify(date)} />                    )}                </Form.Item>                <Button onClick={submit}>提交</Button>            </Form>        </div>    )}const WrappedHorizontalLoginForm = Form.create('asd')(TestForm);export default WrappedHorizontalLoginForm