需求背景
- 指定某一月完整日历,可通过上下月按钮翻月;
- 日历项非本月不可点击,自定义日历项渲染内容;
- 翻月时应判断目标月份在不在指定时间段范围,在则请求数据,不在则给taost提示;
- 日历项包含input,日历(项)分查看、编辑两种状态,编辑又分单个编辑和批量编辑两种模式。
- 日历项数据更改过后需要改日历项标红。
技术方案
- 整体基于el-calendar的自定义内容(element.eleme.cn/#/zh-CN/com… 。
- 日历项数据结构设计如下:
const calendarObj = {
'2021-08-21': {
'_price': 23, // 初始数据
'_stock': 678,
'price': 23, // 双向绑定数据-----通过比对初始数据来标红页面改动
'stock': 678
},
'2021-08-22': {
'_price': 23,
'_stock': 456
'price': 23,
'stock': 456
}
}
这里最好整理成Object形式,便于渲染。原因:ele-calendar的slot暴漏给开发者的是每一天的day,如下:
其中,data的结构如下:
const data = {
"isSelected": false, // 是否已选中当前日历项,可通过此来标记选中的样式
"type": "current-month", // 是否当前月
"day": "2021-08-21"
}
所以,我们渲染日历项时只需要如下即可:
- 针对需求3,可以侦听日历绑定值的变化来判断月份是否变化了。判断目标月份在不在时间段范围内逻辑如下:
/**
* 计算当前月的第一天00:00:00和最后一天23:59:59
* return {}
* @param day 该月某一天
*/
const calcSEDayInMonth = (day='2021-08-31') => {
const date = new Date(day);
date.setDate(1);
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
const date1 = new Date(day);
const m = date1.getMonth();
// 若月份到了11 月,则月分置0,年份进1
if ( m === 11) {
date1.setMonth(0);
date1.setFullYear(date1.getFullYear() + 1);
} else {
// 这里需要先置日为28 确保每个月都有 不然置下个月分时有可能会跳到下下个月
date1.setDate(28);
date1.setMonth(m + 1);
date1.setDate(1);
date1.setHours(0);
date1.setMinutes(0);
date1.setSeconds(0);
}
return {
stDay: date.getTime(),
enDay: date1.getTime() - 1000 // 这里下个月的1号的00:00:00减去1s
}
}
实现过程中的一些小问题
- el-calendar上一月、下一月没有暴漏出事件回调,通过侦听日历组件的v-model来解决;
- el-calendar没有提供禁止非当月日历项的点击事件,通过设置css属性来禁止,如图:
可见,日历项的鼠标也由手变成了箭头。
- el-calendar没有提供日历上下月按钮的禁用功能,可以通过定位元素来解决。
打完收工
乌拉