文章目录
此刻按钮失效原因:使用了禁用未来日期
尝试将禁用日期延后几分钟,这样确实可用。如果禁用未来日期的同时,你又限制了时分秒(selectableRange)的选项,那设置延后也没用。
但是这样的操作又与禁用日期冲突;但是找到了问题原因。
vue源码中此刻按钮的操作;
解决办法:重写此刻按钮点击事件
我研究了很久,没有从官方文档找到有效的解决办法。
只能通过事件重写来解决此问题了
代码(包含禁用未来日期和时分秒的处理)
此代码是基于这篇文章做的优化 el-datepicker禁用未来日期(包含时分秒)type='datetime'
html
<template>
<div class="hello">
<el-date-picker
v-model="time"
ref="datePicker"
type="datetime"
:picker-options="{
disabledDate(time) {
const nowTime = new Date()
return new Date(time).getTime() > nowTime.getTime() + 1 * 60 * 1000
},
selectableRange
}"
@change="changeDate"
@focus="dateFocus"
@blur="dateBlur"
></el-date-picker>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {
time: '',
selectableRange: '00:00:00-23:59:59',
timer: null
}
},
watch: {
time(newTime, oldTime) {
// 在滚动选择时分秒的时候也会被 watch 监听到
// 在这里判断 如果年月日相同,就不再去更新。
const sameDay = new Date(newTime).toLocaleDateString() === new Date(oldTime).toLocaleDateString()
if (sameDay) return
this.updateSelectableRange()
}
},
methods: {
// 日期选择框聚焦:重写事件
// 聚焦后才会弹出日期选择框
// 所以使用 $nextTick 等待日期选择窗口挂载后去操作dom
async dateFocus() {
await this.$nextTick()
const btn = document.querySelector('.el-picker-panel.el-popper .el-picker-panel__footer span')
btn && btn.addEventListener('click', this.changeToNow)
},
// 重写此刻方法
changeToNow() {
const datePicker = this.$refs.datePicker
// 更新 time
this.time = new Date().toLocaleString().replaceAll('/', '-')
// 切换日期后,主动更新selectableRange(及时更新时分秒的禁用范围)
this.updateSelectableRange()
// 在隐藏日期选择器之前接触绑定事件
this.dateBlur()
// 隐藏日期选择框
datePicker.hidePicker()
},
// 失去焦点:接触事件绑定
dateBlur() {
const btn = document.querySelector('.el-picker-panel.el-popper .el-picker-panel__footer span')
btn && btn.removeEventListener('click', this.changeToNow)
},
updateSelectableRange() {
const nowTime = new Date()
const isSame = new Date(this.time).toLocaleDateString() === nowTime.toLocaleDateString()
this.clearTimer()
if (isSame) {
this.selectableRange = `00:00:00-${nowTime.getHours()}:${nowTime.getMinutes()}:${nowTime.getSeconds()}`
// 创建一个定时器,每分钟更新去更新一次禁用范围。
const delay = 60 - nowTime.getSeconds()
this.timer = setTimeout(() => {
this.updateSelectableRange()
}, delay * 1000)
return
}
this.selectableRange = '00:00:00-23:59:59'
},
clearTimer() {
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
},
changeDate() {
// 选中日期之后清除掉定时器
this.clearTimer()
}
}
}
</script>