Element ui 时间选择器 如何调整分钟的步长

新手上路,请多包涵

image.png
element官方默认的分钟步长是1分钟,但现在业务需求以10分钟为单位,即分钟那一列只显示10、20、30,各位大神有什么办法吗?
我有一个想法,是获取分钟的下拉框dom(如下),通过修改dom里的数据方式来完成...这个想法靠谱吗?
image.png

阅读 14.7k
5 个回答

有点奇葩的需求...不过可以试试,把所有不能被10整除的分钟数的对象给去掉,然后把秒数给隐藏起来。
不做样式要求的话其实用几个selector来实现也是挺好的

方案1 选择完了,验证时间的格式是不是以十分钟为间隔的,思路大致是获取到时间的分钟数,然后min%10===0 ,不是就抛异常不允许保存

方案2 自己写两个下拉框拼起来,一个0-23选择时间,一个0-50选择分钟

当解决不了需求的技术难点,就想办法解决需求的痛点

从其他地方抄了一个代码
vue文件:

  <template>
  <div class="app-container">
    <el-date-picker
      time-arrow-control
      :id="'dp-step-30minute-id_'+randId"
      :popper-class="'dp-step-30minute dp-step-30minute-id_'+randId"
      v-model="value"
      type="datetime"
      format="yyyy-MM-dd HH:mm"
      placeholder="选择日期时间"
    >
    </el-date-picker>
  </div>
</template>
<script>

import func_DatePicker from '@/utils/dateTimePicker30minuteStep'

export default {
  name: 'index',
  data() {
    return {
    value: '2021-07-30 12:45:45',
    }
  },
  created() {
  },
  mounted: function() {  // 页面元素渲染之后再触发
    //设置时间选择器步长
    const that = this
    document.body.addEventListener('click', (e) => {
    func_DatePicker(e, function() {
      const timePicker = document.getElementById('dp-step-30minute-id_' + that.randId)
      that.value = timePicker.value
    })
  }, true)
  },
  methods: {
  }
}
</script>

dateTimePicker30minuteStep.js文件:

const func_DatePicker = function(e, callBack) {
  const { type, target, path } = e
  const flag = path.findIndex(v => v.className && v.className.indexOf('dp-step-30minute') > -1)// 判断是点击事件且是dp-step-30minute类
  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 % 30 === 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 === 0) {
          current = 30
        } //到低了,还是当前值
        else {
          current = 0
        }
      } else if (type === 'up') {
        if (current === 30) {
          current = 0
        } //到头了,还是当前值
        else {
          current = 30
        }
      }
      let html = ''
      if (current === 0) {
        html = `<li class="el-time-spinner__item"></li>
            <li class="el-time-spinner__item active">00</li>
            <li class="el-time-spinner__item">30</li>`
      } else if (current === 30) {
        html = `<li class="el-time-spinner__item">00</li>
            <li class="el-time-spinner__item active">30</li>
            <li class="el-time-spinner__item"></li>`
      } else {
        html = `<li class="el-time-spinner__item">${current - 30}</li>
            <li class="el-time-spinner__item active">${current}</li>
            <li class="el-time-spinner__item">${Number(current) + 30}</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-30minute') > -1) {
      return target
    } else {
      return getParents(target, 'dp-step-30minute')
    }

  }

  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-30minute-id')) id = v
    })
    const result = document.getElementById(`${id}`)
    return result
  }
}
export default func_DatePicker
新手上路,请多包涵

image.png 类似这样的,把每个能选的时间计算出来。然后去elementui的样式里面把带disabled的display:none一下。可以说是最简单的方法了,不用查dom之类的,纯用样式的方式做。

推荐问题