以前收藏了一篇自己动手实现日期选择器的插件,最近没什么事,就想着仿照ElementUI的DatePicker,自己也写了一个简易的日期选择器,本以为不会很麻烦,实际动手才发现有很多问题需要解决。并且在写完之后,才发现可扩展性很差,距离ElementUI的水平差的很远,下一步就是把ElementUI的源码学习一下,看清楚自己的差距。
结构
我将这个日期选择做成了Vue的插件的形式,有三个文件:
- index.js
- MyDate.js
- MyDatePicker.vue
index.js
很简单,只有一个方法intstall
,在install
里面注册了全局组件:
import MyDatePicker from './MyDatePicker'
export default {
install(Vue) {
Vue.component('MyDatePicker', MyDatePicker)
}
}
MyDatePicker.vue
是UI部分,在这里定义样式和交互事件,我将数据单独放到了MyDate.js
中,以Class形式导出
数据部分
我的顺序是先完成MyDate.js
的数据部分,一个日期选择器基本结构如下:
最后导出一个二维数组,二维数组外层包含6个数组,对应日期选择器中的每一行的数据,内层数组又包含7个对象元素,对应周一到周日,这样相当于总共有42个元素,正好对应面板中的42个日期。
当选择一个日期后,首先通过new Date
构造函数获得当前日期所在月的第一天及这一天是星期几
// 当前选择日期所在月的第一天及这一天是星期几
const firstDayOfCurrentMonth = new Date(this.current.year, this.current.month - 1);
const firstDayOfWeek = firstDayOfCurrentMonth.getDay();
要注意的是,new Date().getMonth()
的范围是[0, 11]
,和我们日常使用的月份是少1
的。而我在current
里面存的日期是为了显示所用的,已经加过1
了,所以需要在上面减1
接下来,通过两层的遍历来生成我们所需要的二维数组,外层遍历是对应的是行数据:
for (let row = 0; row < 6; row++) {
}
关键是内层数据,假设我们选择的就是2019年6月,6月1日是星期六,在二维数组的内部数组里面的七个元素,应该吻别对应['日', '一', '二', '三', '四', '五', '六']
,现在6月1日星期六