Vue版本的日历
本文主要还是熟悉Date的API,以及Vue的基础用法。目前实现效果如下:
准备
- 如何实现点击年月日的切换,以及日历的展示
- 应该传入哪些参数?提供哪些参数?
日历展示
其实很简单,只需要提供本月的第一天,并判断是周几,然后获取到列表第一天的时间戳,使用计算属性来返回当月42天的时间戳数组,用v-for
两次列表渲染即可获得对应的值:
// 本月第一天
let currentFristDay = utils.getDate(this.time.year, this.time.month, 1);
// 本月第一天是周几
let week = currentFristDay.getDay();
// 获取列表第一天的时间戳
let startDay = currentFristDay - week * 60 * 60 * 1000 * 24;
var arr = [];
// 循环42天
for (let i = 0; i < 42; i++) {
arr.push(new Date(startDay + i * 60 * 60 * 1000 * 24));
}
return arr;
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
同时绑定对应的类名,添加不同的样式:
:class="[
{notCurrentMonth: !isCurrentMonth(visibleDays[(i-1)*7+(j-1)])},
{today: isToday(visibleDays[(i-1)*7+(j-1)])},
{select: isSelect(visibleDays[(i-1)*7+(j-1)])}]"
1
2
3
4
2
3
4
年份与月份切换
只需要获取当前的年份或者月份,利用setMonth
和setFullYear
这两个方法就可以做到年月份切换,不需要对年份以及每个月做相应的判断,很简单。
重点:实现点击其余区域则隐藏
使用自定义指令实现,并利用vnode.context
获取对应的DOM,比ref会优雅些,注意在选择年份和月份使用v-show
而不是v-if
,否则会导致el.contains(e.target)
为false,弹出框隐藏。
directives: {
clickOutside: {
// 指令的声明周期
bind(el, bindings, vnode) {
// 把事件绑定到document上,判断点击的是否是这个元素
let handler = e => {
if (el.contains(e.target)) {
if (!vnode.context.isVisible) {
vnode.context.focus();
}
} else {
if (vnode.context.isVisible) {
vnode.context.blur();
}
}
};
el.handler = handler;
document.addEventListener("click", handler);
},
unbind(el) {
document.removeEventListener("click", el.handler);
delete el.handler;
}
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
总结
- Vue的基本操作
- 熟悉Date的API
优化
- [ ] 暴露更多的接口,具体参照ElementUI
- [ ] 提供更细致的时间