el-date-picker datetimerange 限制时分秒

本文目标:

在vue2场景下,实现el-date-picker组件的,type为datetimerange时,限制时分秒的功能。

我的场景是,希望,当开始日期和结束日期一致时,选择了开始时间,再去选择结束时间时,这个结束时间选择器里,早于开始时间的都置灰,鼠标经过有禁用的效果

网上搜了很多文章都是type=datetime的场景,不符合我的需求

核心思路:因为该选择器,针对type为datetimerange时,没有直接去限制时分秒的api写在官方文档中,所以,我的做法是结合dom操作和点击事件来实现。

1. 第一步:拿dom,绑定事件

在点击时间选择框的一刹那,去拿我们需要的dom容器,在时间选择器的focus事件时触发

diff 复制代码
        <el-date-picker
          v-model="searchcond.searchPeriod"
          type="datetimerange"
          :range-separator="$t('log.to')"
          :start-placeholder="$t('log.startTime')"
          :end-placeholder="$t('log.endTime')"
          :picker-options="pickerOptions"
          @change="validateDate"
+          @focus="getPickerDom"
          @blur="deletePickerDom"
          ref="datetime"
        >

getPickerDom函数里面,我们去拿对应的dom

js 复制代码
    getPickerDom () {
      this.$nextTick(() => {
        // 开始日期的input
        this.startDate = document.querySelector('.el-picker-panel .el-date-range-picker__editors-wrap:first-of-type .el-date-range-picker__time-picker-wrap:first-of-type .el-input__inner')
        // 开始时间的input
        this.startTime = document.querySelector('.el-picker-panel .el-date-range-picker__editors-wrap:first-of-type .el-date-range-picker__time-picker-wrap:last-of-type .el-input__inner')
        // 确定按钮的button
        this.sureBtn = document.querySelector('.el-picker-panel .el-date-range-picker__editors-wrap:first-of-type .el-date-range-picker__time-picker-wrap:last-of-type .el-time-panel__btn.confirm')
        // 结束日期的input
        this.endDate = document.querySelector('.el-picker-panel .el-date-range-picker__editors-wrap:last-of-type .el-date-range-picker__time-picker-wrap:first-of-type .el-input__inner')
        // 日期选择器输入框输入内容失去焦点触发
        this.startDate.addEventListener('blur', this.formatTimeDisable)
        this.startTime.addEventListener('blur', this.formatTimeDisable)
        // 时间选择器输入框点击确定的时候触发
        this.sureBtn.addEventListener('click', this.formatTimeDisable)
      })
    },

对应的startDate startTime sureBtn endDate请在data里面自己声明好鸭~

  • 开始日期是这个input
  • 开始时间是这个input

  • 结束日期是这个input

  • 确定按钮是这个btn

  • 给startDate endDate sureBtn绑定blur事件的原因?我理解过来是,当选择了开始日期和结束日期,和开始时间这个三个input,以及点击了这个btn按钮的时候,执行该函数,更新操作。

2. 第二步:事件处理的逻辑

formatTimeDisable函数内部要做什么操作?

js 复制代码
formatTimeDisable () {
      try {
        const picker = this.$refs.datetime?.picker
        // 拿到结束时间的"选择器"
        const { maxTimePicker } = picker.$refs
        // 判断,只有在开始日期和结束日期相等时,才去限制时分秒
        if (this.startDate.value === this.endDate.value) {
          // arr必须是二维数组,意味着"selectableRange"限制的时间范围可以有多个
          let arr = [
            [new Date(`${this.startDate.value} ${this.startTime.value}`), new Date(`${this.startDate.value} ${this.endTimeFormat}`)]
          ]
          maxTimePicker.selectableRange = arr
          // 这样限制的时分秒,时和分会有禁用的效果,但是秒没有禁用置灰的效果,但是也无法点击了,也不会影响开始时间
        } else {
          // 开始时间和结束时间不相等,不限制时分秒
          maxTimePicker.selectableRange = []
        }
      } catch (error) {
        console.log(error, 'error');
      }
    },
  1. const picker = this.$refs.datetime?.picker
  • this.$refs.datetime拿到的是这个
  • this.$refs.datetime?.picker拿到的是这个,是我们要操作的
  1. const { maxTimePicker } = picker.$refs

picker.$refs里面有三个,

maxTimePicker里面是结束时间的选择器,我们要给这个里面的选择器进行禁用

  1. if (this.startDate.value === this.endDate.value) 拿到开始和结束的日期,比较是不是同一天,如果不是同一天,不需要对结束日期做出校验,走else maxTimePicker.selectableRange = \[\] selectableRange里面是一个二维数组,这个用来表示可以选择的日期范围,你看这里的显示的表示4.19日我可以选择从11:12:00到23:59:59的时间
  1. 当开始日期和结束日期是同一天,我们就是修改selectableRange的日期
  • arr是二维数组,不然就会报错
  • 注意,startDate startTime startDate都是我们之前拿得到的值,从input表单.value直接拿到(这是dom的语法啦)
  • endTimeFormat是在data里面定义的,是一个默认值,我是这样写的endTimeFormat: '23:59:59'
  • maxTimePicker.selectableRange = arr 这样去进行赋值
js 复制代码
// arr必须是二维数组,意味着"selectableRange"限制的时间范围可以有多个
let arr = [
    [new Date(`${this.startDate.value} ${this.startTime.value}`), new Date(`${this.startDate.value} ${this.endTimeFormat}`)]
]
  1. 在失去焦点的时候,去清空这些事件,防止内存泄漏
js 复制代码
this.startTime.removeEventListener('blur', this.formatTimeDisable)
this.startDate.removeEventListener('blur', this.formatTimeDisable)
this.sureBtn.removeEventListener('click', this.formatTimeDisable)
this.startDate = null
this.startTime = null
this.sureBtn = null
this.endDate = null
  1. 只是美中不足的是,在秒这里没能限制好

原因在于,element-ui里面针对time-spinner组件,没有给秒增加disabled属性 时和分都有

唯独秒没有

相关推荐
东方小月6 小时前
从零开发一个 Coding Agent(四):使用状态机校验大模型事件流
前端·人工智能·后端
Csvn6 小时前
🧩 ESM vs CJS 混用的 7 个「天坑」——从 TypeScript 编译到 Node 与浏览器
前端
Csvn6 小时前
🎯 Web 性能 API 集合:Performance Observer 的 5 个冷门妙用
前端
Csvn6 小时前
深入 React 闭包陷阱:从根源上理解并根治 stale closure
前端
whyfail6 小时前
前端学 Spring Boot(8):接口为什么越用越慢?
前端·spring boot·后端
用户059540174467 小时前
LangChain 记忆测试踩坑实录:这两个坑让我排查了 4 小时
前端·css
程序员黑豆7 小时前
鸿蒙应用开发:@Monitor 装饰器使用教程
前端·harmonyos
用户938515635077 小时前
从零构建《天龙八部》知识库:EPUB 加载→文本分割→向量嵌入→Milvus 存储→RAG 问答,一条链路打通
javascript·人工智能·全栈
SamChan908 小时前
在Web应用中集成PDF多语言翻译功能:PDFTranslator API实战指南
前端·python·ai·pdf·yapi·机器翻译
kyriewen8 小时前
AI Agent 9秒删光了生产数据库——我给自己的项目做了5个紧急检查
前端·ai编程·claude