如何设置element-ui datetimepicker默认时间及解决computed绑定报错?
Element UI DateTimePicker绑定计算属性滚动报错问题
问题场景
需要为Element UI的datetimepicker时间范围选择器设置默认时间范围为当日00:00:00至23:59:59。实际测试时,v-model绑定data中定义的value1功能完全正常,但绑定computed计算属性中定义的value2时,操作选择器滚动选择时间就会触发报错,原实现代码如下:
new Vue({ el: '#app', data: function () { return { value1: [new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDay(), 0, 0, 0), new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDay(), 23, 59, 59) ], } }, computed: { value2: { get() { let date = new Date() let y = date.getFullYear() let m = date.getMonth() + 1 let d = date.getDay() let start = new Date(y, m, d, 0, 0, 0) let end = new Date(y, m, d, 23, 59, 59) return [start, end] }, set(newVal) { this.value2 = newVal } }, }, methods: { change(e) { console.log('eee', e); } } })
报错原因
三个问题叠加导致异常:
- setter无限递归死循环:计算属性
value2的setter中直接给this.value2赋值,这个操作本身会再次触发value2的setter,形成无限递归调用。滚动选择时间时组件会尝试更新绑定值,一旦触发setter就会直接栈溢出抛错,这是最核心的报错原因。 - 日期API调用错误:getter中使用
getDay()获取日期,这个API的返回值是当前星期数(取值0-6对应周日到周六),不是当月的日期号数;同时获取月份时额外做了+1处理,但new Date()构造函数的月份参数本身是0起始(0代表1月,11代表12月),传入+1后的月份会导致默认时间多算1个月,就算不报错默认值也是错误的。 - 返回值引用不稳定:getter每次被访问都会返回一个全新创建的数组实例,组件内部做值变更检测时,会判定绑定值每次都发生了变化,滚动选择时高频触发不必要的重渲染,进一步提升了报错概率。
修复方案
如果要通过计算属性实现默认值,需要搭配data中的独立字段存值,修正日期API的错误调用,修复后代码如下:
new Vue({ el: '#app', data: function () { return { // 实际存储选择器选中值的字段 pickerValue: null } }, computed: { value2: { get() { // 已有选中值直接返回,无值则返回默认当日范围 if (this.pickerValue) return this.pickerValue const date = new Date() const y = date.getFullYear() const m = date.getMonth() // 月份参数0起始,不需要+1 const d = date.getDate() // 用getDate获取当月日期号数 const start = new Date(y, m, d, 0, 0, 0) const end = new Date(y, m, d, 23, 59, 59) return [start, end] }, set(newVal) { // 赋值给data中的存值字段,不要给计算属性本身赋值 this.pickerValue = newVal } }, }, methods: { change(e) { console.log('选值变更', e); } } })
内容的提问来源于stack exchange,提问作者listen936
相关产品推荐
相关产品推荐

