网上查el-calendar相关的按钮点击事件文章,清一色都是在mounted挂载阶段通过document.querySelector绑定类名添加点击事件。
我想说为啥要弄得这么麻烦?el-calendar组件标签中v-model绑定了一个Date/string/number的时间值,无论点击上述哪个按钮,该值都是会改变的。
而我们想要实现的是当该时间值改变时(例如变成上个月或下个月或其他时间变回今天)执行某个事件,那直接用watch来监听该值来实现逻辑不就更方便且简单了么
放一下我这边的代码:
el-calendar组件标签,v-model绑定的变量命名为calendarDate:
<el-calendar v-model="calendarDate">
<template slot="dateCell" slot-scope="{ date, data }">
<p :class="data.isSelected ? 'is-selected' : ''">
{{ data.day.split("-").slice(1).join("-") }}
{{ data.isSelected ? "✔️" : "" }}
</p>
<el-input
v-if="data.type == 'current-month'"
:disabled="timeOptions(date)"
v-model="calendarData[date.getDate() - 1]"
step="0.01"
type="number"
size="mini"
:min="0"
>
</el-input>
</template>
</el-calendar>
js代码:
(这里用到了momentjs,一个非常方便的时间处理类库,建议使用,官方文档传送门:Moment.js)
let moment = require("moment");
data() {
return {
// 让el-calendar绑定一个Date型的值,初始为当前时间
calendarDate: new Date(),
calendarData: [0],
};
},
watch: {
// 用watch监听calendarDate
// 1. 我自己项目中用到的较为简单的逻辑:
// 即不管点击了上月还是下月,只要时间改变,就执行函数initFormData,调用接口,将请求到的新数据重新渲染在el-calendar组件的内容上
calendarDate(val, oldVal) {
if (
val &&
moment(val).format("YYYY-MM") != moment(oldVal).format("YYYY-MM")
) {
this.initFormData(val);
}
},
// 2. 更严谨的写法,直接复制粘贴代码的朋友记得把上方的1.删掉再使用
calendarDate(val, oldVal) {
if (
val &&
moment(val).format("YYYY-MM-DD") == moment().format("YYYY-MM-DD")
) {
console.log("点击了‘今天’按钮");
} else if (
val &&
moment(val).toDate() < moment(oldVal).startOf("month").toDate()
) {
console.log("点击了‘上个月’按钮");
} else if (
val &&
moment(val).toDate() > moment(oldVal).endOf("month").toDate()
) {
console.log("点击了‘下个月’按钮");
} else {
console.log("点击了" + moment(val).format("YYYY-MM") + "的按钮");
}
},
},
实操效果:
不过这种实现方式有个小bug:当天是某个月的1日时,通过点击“上个月”和“下个月”按钮回到当月,就会执行点击“今日”的逻辑事件。这个就根据各位项目中的用法自行优化了。
直接绑定点击事件
使用最开始说的那种在mounted里绑定点击事件的方法,可以避免上述bug,在这里也一起贴上来,可自行择优使用:
<script>
export default {
name: "Calendar",
data() {
return {
calendarDate: new Date(),
};
},
components: {},
mounted() {
this.$nextTick(() => {
// 点击前一个月
let prevBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(1)"
);
prevBtn.addEventListener("click", () => {
this.judgeDate(this.calendarDate);
});
let dayBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(2)"
);
dayBtn.addEventListener("click", () => {
this.judgeDate(this.calendarDate);
});
let nextBtn = document.querySelector(
".el-calendar__button-group .el-button-group>button:nth-child(3)"
);
nextBtn.addEventListener("click", () => {
this.judgeDate(this.calendarDate);
});
});
},
methods: {
// 判断时间
judgeDate(dateVal) {
console.log(dateVal);
},
},
};
</script>
更多日历组件的项目应用可详见我的下一篇文章,例如给每一天加input输入框、超过当天时间和跨一个月前的时间禁用输入框等等: