需求:需要先让用户选择一个时间区间,然后再这个时间区间中,让用户再次去单选其种特殊日期。
思路:
1.先用Antd组件库中日期选择DatePicker.RangePicker实现让用户选择时间区间
2.在选择完时间区间后,用这个时间区间,弹出一个在这个时间区间范围内的日历组件Calendar
3.通过Calendar组件(日历)的onSelect(点击事件)获得点击value,然后通过dateCellRender(自定义渲染日期单元格)将选中的时间给用户颜色提示
4.最后将日期选择,还有区间内时间传给后端
第一步:先用Antd组件库中日期选择DatePicker.RangePicker实现让用户选择时间区间
页面:
代码:
<RangePicker
defaultValue={[moment(archiveStartTime, 'YYYY-MM-DD'), moment(archiveEndTime, 'YYYY-MM-DD')]}
onChange={this.archiveTime}
format={'YYYY-MM-DD'}
/>
archiveTime = async (date: any, dateString: any) => { //日期改变
//这时候 先弹框,并且暂存时间区间
this.setState({
restVis: true, //弹框
dateString, //暂存时间区间
})
}
第二步,第三步
2.在选择完时间区间后,用这个时间区间,弹出一个在这个时间区间范围内的日历组件Calendar
3.通过Calendar组件(日历)的onSelect(点击事件)获得点击value,然后通过dateCellRender(自定义渲染日期单元格)将选中的时间给用户颜色提示
刚弹出:选中后:
弹框中装入一个日历组件
<Modal
title="选择休息日"
visible={restVis} //显示
onOk={this.restHandleOk} //确定
onCancel={this.restHandleCancel} //取消
>
<Calendar
className={styles.backgrand} //改变默认选中蓝色的样式 不然每次点击颜色变化会影响用户选中判断
fullscreen={false} //不显示大日历
onSelect={this.onSelect} //点击时间
dateCellRender={this.dateCellRender} //日期渲染
validRange={[moment(archiveStartTime), moment(archiveEndTime)]} //可选时间区间,这边取上面日期选择组件的值
/>
</Modal>
上面日历组件中用global改变组件样式
.backgrand {
:global {
.ant-fullcalendar-selected-day .ant-fullcalendar-value,
.ant-fullcalendar-month-panel-selected-cell .ant-fullcalendar-value {
background-color: #fff !important;
color: #595959;
}
}
}
日历组件两个事件
onSelect = (date: any) => { // 点击选择日期回调
const { restDay } = this.state; //选中值集合
let vis = true //判断这个值是否选中
if (restDay && Array.isArray(restDay)) {
restDay.map((item: any) => {
if (item == moment(date).format('YYYY-MM-DD')) {
vis = false
}
})
if (vis) { restDay.push(moment(date).format('YYYY-MM-DD')) } //如果未选中 增加这个选中值
if (!vis) { restDay.splice(restDay.indexOf(moment(date).format('YYYY-MM-DD')), 1) }//如果已选中 删除这个选中值
}
this.setState({ restDay })
}
dateCellRender = (val: any) => { //自定义渲染日期单元格,返回内容会被追加到单元格
const { restDay } = this.state; //选中值集合
if (restDay && Array.isArray(restDay) && restDay.length > 0 && restDay.indexOf(moment(val).format('YYYY-MM-DD')) > -1) {
return <div style={{ position: 'relative' }}>
<div style={{ //这边这个样式如果不处理,默认是在每个时间的下方
color: 'red', backgroundColor: 'green',
width: 25, height: 23, opacity: 0.4,
position: 'absolute', left: 20, bottom: 18,
}}></div>
</div>
}
}
最终Modal弹框打开关闭事件,其中restDay,dateString就是最终用户一套花里胡哨操作后,我们最终需要得到两个参数
restHandleOk = async () => {
const { dateString, restDay } = this.state
await this.updateState({
archiveStartTime: dateString[0],
archiveEndTime: dateString[1],
});
console.log('此时单独选中:', restDay)
console.log('此时时间区间:', dateString)
this.restHandleCancel()
}
restHandleCancel = () => {
this.setState({ restVis: false })
}