基于el-calendar二次开发的若干问题

2,605 阅读2分钟

需求背景

  1. 指定某一月完整日历,可通过上下月按钮翻月;
  2. 日历项非本月不可点击,自定义日历项渲染内容;
  3. 翻月时应判断目标月份在不在指定时间段范围,在则请求数据,不在则给taost提示;
  4. 日历项包含input,日历(项)分查看、编辑两种状态,编辑又分单个编辑和批量编辑两种模式。
  5. 日历项数据更改过后需要改日历项标红。

技术方案

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,如下:

image.png 其中,data的结构如下:

const data = {
  "isSelected": false, // 是否已选中当前日历项,可通过此来标记选中的样式
  "type": "current-month", // 是否当前月
  "day": "2021-08-21"
}

所以,我们渲染日历项时只需要如下即可:

image.png

  • 针对需求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
   }
}

实现过程中的一些小问题

  1. el-calendar上一月、下一月没有暴漏出事件回调,通过侦听日历组件的v-model来解决;
  2. el-calendar没有提供禁止非当月日历项的点击事件,通过设置css属性来禁止,如图: image.png 可见,日历项的鼠标也由手变成了箭头。
  3. el-calendar没有提供日历上下月按钮的禁用功能,可以通过定位元素来解决。

打完收工

乌拉