这是 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 (
{selectedValue.length > 0 ? selectedValue.map(one =>
{one}
setSelectedValueChange(selectedValue.filter(item => item != one))} />
) : 请选择日期}
setIsShow(!isShow)}>
{isShow ? : null}
)
}
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
setYearNumber((Number(yearNumber) - 1))} />
{yearNumber}年{monthNumber}月
setYearNumber(Number(yearNumber) + 1)} />
{weekArr.map(one => {one})}
{daysList.map(one => {
const nowValue = moment(one.date).format('YYYYMMDD')
const isSelected = selectedValue.includes(nowValue)
return changeDays(nowValue, isSelected)}
className={`common-days ${one.type == 'now' ? 'now-days' : 'other-days'} ${isSelected ? ' common-days-active' : ''}`}
key={`${one.type}-${one.value}`}>
{one.value}
})}
}
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 (
{selectedValue.length > 0 ? selectedValue.map(one =>
{one}
setSelectedValueChange(selectedValue.filter(item => item != one))} />
) : 请选择日期}
setIsShow(!isShow)}>
{isShow ? : null}
)
}
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
setYearNumber(yearNumber - 1)} />
{yearNumber}年
setYearNumber(yearNumber + 1)} />
{monthArr.map(one => {
const value = `${yearNumber}${one.value}`
const isCanSelected = canSelectedList.includes(value)
const isSelected = selectedValue.includes(value)
return isCanSelected ? selectedMonth(value, isSelected)}>{one.name}月
: {one.name}月
})}
}
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 (
{getFieldDecorator('@param_month', {
initialValue: date,
rules: [{ required: true, message: 'Please input your Password!' }],
})(
)}
*/}
{getFieldDecorator('@param_month23', {
initialValue: ["20200322", "20200212"],
rules: [{ required: true, message: 'Please input your Password!' }],
})(
)}
)
}
const WrappedHorizontalLoginForm = Form.create('asd')(TestForm);
export default WrappedHorizontalLoginForm