elementUI的DateTimePicker设置分钟步长为五分钟

问题

项目中希望elementUI 的DateTimePicker达到与TimePicker相同的固定时间点,即设置步长的效果,但elementUI目前并未提供此功能,所以我自己用dom的方式实现改功能

代码实现

vue部分

复制代码
<template>
  <div>
    <el-date-picker
        time-arrow-control
        :id="'dp-step-5minute-id_'+randId"
        :popper-class="'dp-step-5minute dp-step-5minute-id_'+randId"
        v-model="value"
        type="datetime"
        format="yyyy-MM-dd HH:mm:ss"
        value-format="yyyy-MM-dd HH:mm:ss"
        placeholder="选择日期时间">
    </el-date-picker>
    <el-date-picker
        time-arrow-control
        :id="'dp-step-5minute-id_'+randId1"
        :popper-class="'dp-step-5minute dp-step-5minute-id_'+randId1"
        v-model="value1"
        type="datetime"
        format="yyyy-MM-dd HH:mm:ss"
        value-format="yyyy-MM-dd HH:mm:ss"
        placeholder="选择日期时间1">
    </el-date-picker>

    <br>
    <br>
    <el-button @click="alertPickerValue">获取数据</el-button>
  </div>
</template>

<script>
import func_DatePicker from '../utils/set_dp-step-5minute'
export default {
  name: 'demo',
  data() {
    return {
      value: "2021-07-30 12:45:45",
      value1: "2021-07-30 2:05:33",
      randId:new Date().getTime(),
      randId1:new Date().getTime() + 10
    };
  },
  destroyed() {
    // 注销事件
  },
  mounted(){
    const _this = this
    try {
      document.body.addEventListener('click', (e) => {
        func_DatePicker(e, function() {
          const timePicker = document.getElementById('dp-step-5minute-id_' + _this.randId)
          const timePicker1 = document.getElementById('dp-step-5minute-id_' + _this.randId1)
          _this.value = timePicker.value
          _this.value1 = timePicker1.value
        })
      }, true)
    } catch (e) {
      console.log(e)
    }
  },
  methods:{
    alertPickerValue(){
      alert(this.value)
      alert(this.value1)
    }
  }
}
</script>
复制代码

 

set_dp-step-5minute.js文件

复制代码
const func_DatePicker = function(e,callBack){
    const { type,target,path} = e
    const flag = path.findIndex(v => v.className && v.className.indexOf('dp-step-5minute')>-1)// 判断是点击事件且是dp-step-5minute类
    if(type === 'click' && (flag > -1)) {
        // 已绑定事件的容器做标记,用于防止重复绑定
        const container = getDateContainer(target)
        const isBindClick = container.getAttribute('isBindClick')
        if(isBindClick) return false
        container.setAttribute('isBindClick',true)
        const wrapper = container.querySelector('.el-date-picker__time-header .el-date-picker__editor-wrap:nth-child(2)')
        const spinner = wrapper.querySelector('.el-time-panel .el-time-spinner__wrapper:nth-child(2)')
        const HourSpinner = wrapper.querySelector('.el-time-panel .el-time-spinner__wrapper:nth-child(1)')
        const SecondSpinner = wrapper.querySelector('.el-time-panel .el-time-spinner__wrapper:nth-child(3)')
        const commitBtn = container.querySelector('.el-picker-panel__footer button:nth-child(2)')
        // 当前分钟数
        let currentMinute = 0
        // 移除事件
        // todo......

        // 绑定事件
        // time-spinner
        const spinnerEle = spinner.querySelector('.el-time-spinner__list')

        // time input 绑定click事件 - 初始化数据
        const inputEle = wrapper.querySelector(".el-input__inner")
        const func_inputEle = function(){
            const current = getCurrent()
            setMinute(current)
        }
        inputEle.addEventListener('click',func_inputEle)

        // time input 绑定change事件
        const func_change_inputEle = function(){
            setInputVal()
        }

        // 箭头up绑定事件(上)
        const oldUpEle = spinner.querySelector(".el-icon-arrow-up")
        const newUpEle = createEle('i','el-time-spinner__arrow el-icon-arrow-up','')
        oldUpEle.parentNode.replaceChild(newUpEle,oldUpEle);
        const func_upEle = function(){
            const current = getCurrent()
            setMinute(current,'up')
        }
        newUpEle.addEventListener('click',func_upEle)
        // 箭头down绑定事件(下)
        const oldDownEle = spinner.querySelector(".el-icon-arrow-down")
        const newDownEle = createEle('i','el-time-spinner__arrow el-icon-arrow-down','')
        oldDownEle.parentNode.replaceChild(newDownEle,oldDownEle);
        const func_downEle = function(){
            const current = getCurrent()
            setMinute(current,'down')
        }
        newDownEle.addEventListener('click',func_downEle)

        // 小时、秒 上下箭头触发input的change
        const h_DownEle = HourSpinner.querySelector(".el-icon-arrow-down")
        const h_UpEle = HourSpinner.querySelector(".el-icon-arrow-up")
        const S_DownEle = SecondSpinner.querySelector(".el-icon-arrow-down")
        const S_UpEle = SecondSpinner.querySelector(".el-icon-arrow-up")
        h_DownEle.addEventListener('click',func_change_inputEle)
        h_UpEle.addEventListener('click',func_change_inputEle)
        S_DownEle.addEventListener('click',func_change_inputEle)
        S_UpEle.addEventListener('click',func_change_inputEle)

        // 绑定确定按钮点击事件
        const func_commitBtn = function () {
            const resultInput = getResultInput(container)
            const timeVal = inputEle.value
            const value = resultInput.value
            resultInput.value = value.split(" ")[0]+" "+timeVal
            callBack()
        }
        commitBtn.addEventListener('click',func_commitBtn)
        // 获取当前分钟数
        // eslint-disable-next-line no-inner-declarations
        function getCurrent(){
            const timeVal = inputEle.value
            let current = 0
            if(timeVal){
                const minute = Number(timeVal.split(":")[1])
                if(minute % 5 === 0)current = minute
            }
            return Number(current)
        }
        // 设置time-spinner的html,并计算返回current
        // eslint-disable-next-line no-inner-declarations
        function setMinute(current,type){
            if(type === 'down') {
                if(current === 55) {current = 55} //到低了,还是当前值
                else current = current + 5
            }else if(type === 'up') {
                if(current === 0) {current = 0} //到头了,还是当前值
                else current = current - 5
            }
            let html = ''
            if(current === 0){
                html = `<li class="el-time-spinner__item"></li>
            <li class="el-time-spinner__item active">0</li>
            <li class="el-time-spinner__item">5</li>`
            }else if(current === 55){
                html = `<li class="el-time-spinner__item">50</li>
            <li class="el-time-spinner__item active">55</li>
            <li class="el-time-spinner__item"></li>`
            }else{
                html = `<li class="el-time-spinner__item">${current-5}</li>
            <li class="el-time-spinner__item active">${current}</li>
            <li class="el-time-spinner__item">${Number(current)+5}</li>`
            }
            spinnerEle.innerHTML = html
            currentMinute = current
            setInputVal()
        }
        // 设置input分钟数的值
        // eslint-disable-next-line no-inner-declarations
        function setInputVal() {
            const timeVal = inputEle.value
            let arr = ['00','00','00']
            if(timeVal){
                arr = timeVal.split(":")
            }
            arr[1] = currentMinute<10 ? '0'+currentMinute : currentMinute
            inputEle.value = arr.join(':')
        }
        // 创建节点
        // eslint-disable-next-line no-inner-declarations
        function createEle(type,classname,text){
            const element = document.createElement(type);
            element.className = classname;
            const textNode = document.createTextNode(text);
            element.appendChild(textNode);
            return element
        }
    }

    // 公共方法
    function getDateContainer(target){
        const className = target.className
        if(className.indexOf('dp-step-5minute')>-1) {
            return target
        }else{
            return getParents(target, 'dp-step-5minute')
        }

    }
    function getParents(el, parentsClass) {
        while(el.parentNode){
            el = el.parentNode
            if(el.className.indexOf(parentsClass)>-1) {
                return el
            }
        }
        return null;
    }
    function getResultInput(container) {
        const classList = container.classList
        let id = ''
        classList.forEach(v => {
            if(v.startsWith('dp-step-5minute-id')) id = v
        })
        const result = document.getElementById(`${id}`)
        return result
    }
}
export default func_DatePicker
复制代码

 

最终展示

 

posted @   卷叶小树  阅读(3588)  评论(2编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示