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
最终展示
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .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吗?