vue3+elementPlus el-date-picker 自定义禁用状态hook 实现结束时间不能小于开始时间

背景:

复制代码
elementPlus的el-date-picker中,相较于了element,升级了写法,
如果为每一个开始时间、结束时间设置禁用状态,在全局中会造成代码冗余。
所以在vue3中采用自定义hook的方式,实现代码复用。

1、实现如下效果:

复制代码
开始时间:今天过后日期不可选,如p1所示;
结束时间:必须大于开始时间,精确到时分秒,如p2所示。

2、编写hook(useDisabledDate.ts)

复制代码
export function useDisabledDate() {
	// 开始时间与结束时间,采用赋值的方式
    const forDisStartTime = ref<Date | string>()
    const forDisEndTime = ref<Date | string>()
    
    // 不可用的开始时间,如图1所示
    const disabledStartTime = (data: Date) => {
        return data.getTime() > new Date().getTime()
    }

    // 结束时间--日期
    const disabledEndTimeDate = (data: Date) => {
        if (forDisStartTime.value) {
            const hours = new Date(forDisStartTime.value).getHours(),
                seconds = new Date(forDisStartTime.value).getSeconds(),
                minutes = new Date(forDisStartTime.value).getMinutes()
            if (hours == 0 && minutes == 0 && seconds == 0) return data.getTime() < new Date(forDisStartTime.value).getTime() - 1000
            else return data.getTime() < new Date(forDisStartTime.value).getTime() - 8.64e7
        }
    }
// 结束时间--时
    const disabledEndTimeHours = () => {
        const hours = new Date(forDisStartTime.value as Date).getHours(),
            sY = new Date(forDisStartTime.value).getFullYear(),
            sM = new Date(forDisStartTime.value).getMonth(),
            sD = new Date(forDisStartTime.value).getDate(),
            eY = new Date(forDisEndTime.value).getFullYear(),
            eM = new Date(forDisEndTime.value).getMonth(),
            eD = new Date(forDisEndTime.value).getDate()
        const arrs = []
        if (sY == eY && sM == eM && sD == eD) {
            for (let i = 0; i < 24; i++) {
                if (hours <= i) continue
                arrs.push(i)
            }
        }
        return arrs
    }
    // 结束时间--分
    const disabledEndTimeMinutes = () => {
        const minutes = new Date(forDisStartTime.value as Date).getMinutes(),
            sY = new Date(forDisStartTime.value).getFullYear(),
            sM = new Date(forDisStartTime.value).getMonth(),
            sD = new Date(forDisStartTime.value).getDate(),
            eY = new Date(forDisEndTime.value).getFullYear(),
            eM = new Date(forDisEndTime.value).getMonth(),
            eD = new Date(forDisEndTime.value).getDate()
        const arrs = []
        if (sY == eY && sM == eM && sD == eD) {
            for (let i = 0; i < 60; i++) {
                if (minutes <= i) continue
                arrs.push(i)
            }
        }
        return arrs
    }
    // 结束时间--秒
    const disabledEndTimeSeconds = () => {
        const seconds = new Date(forDisStartTime.value).getSeconds(),
            sY = new Date(forDisStartTime.value).getFullYear(),
            sM = new Date(forDisStartTime.value).getMonth(),
            sD = new Date(forDisStartTime.value).getDate(),
            eY = new Date(forDisEndTime.value).getFullYear(),
            eM = new Date(forDisEndTime.value).getMonth(),
            eD = new Date(forDisEndTime.value).getDate()
        const arrs = []
        if (sY == eY && sM == eM && sD == eD) {
            for (let i = 0; i < 60; i++) {
                if (seconds <= i) continue
                arrs.push(i)
            }
        }
        return arrs
    }
    return {
        forDisStartTime,
        forDisEndTime,
        disabledStartTime,
        disabledEndTimeDate,
        disabledEndTimeHours,
        disabledEndTimeMinutes,
        disabledEndTimeSeconds
    }
}

3、在.vue文件中使用该hook

复制代码
<script setup lang="ts">
// 引入
import { useDisabledDate } from '@/hooks/useDisabledDate'

const formItem = reactive({
	beginTime: '',
	endTime: ''
})

// #region disabled-date
const {
    forDisStartTime,
    forDisEndTime,
    disabledStartTime,
    disabledEndTimeDate,
    disabledEndTimeHours,
    disabledEndTimeMinutes,
    disabledEndTimeSeconds
} = useDisabledDate()

// 赋值开始时间
watch(
    () => formItem.beginTime,
    (newTime) => {
        forDisStartTime.value = newTime
    },
    { immediate: true }
)
// 赋值结束时间
watch(
    () => formItem.endTime,
    (newTime) => {
        forDisEndTime.value = newTime
    },
    { immediate: true }
)
// #endregion
</script>

<template>
	<el-form :model="formItem" ref="formRef" :rules="formRules" label-width="120px" size="small">
		<el-form-item label="开始时间" prop="beginTime">
		     <el-date-picker
		         v-model="formItem.beginTime"
		         type="datetime"
		         :clearable="false"
		         value-format="YYYY-MM-DD HH:mm:ss"
		         :disabled-date="disabledStartTime"
		     >
		     </el-date-picker>
		 </el-form-item>
		 <el-form-item label="结束时间" prop="endTime">
		     <el-date-picker
		         v-model="formItem.endTime"
		         type="datetime"
		         style="width: 100%"
		         :clearable="false"
		         value-format="YYYY-MM-DD HH:mm:ss"
		         :disabled-date="disabledEndTimeDate"
		         :disabled-hours="disabledEndTimeHours"
		         :disabled-minutes="disabledEndTimeMinutes"
		         :disabled-seconds="disabledEndTimeSeconds"
		     >
		     </el-date-picker>
		 </el-form-item>
	</el-form>
</template>
相关推荐
bearpping6 小时前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx
@大迁世界6 小时前
07.React 中的 createRoot 方法是什么?它具体如何运作?
前端·javascript·react.js·前端框架·ecmascript
January12076 小时前
VBen Admin Select 选择框选中后仍然显示校验错误提示的解决方案
前端·vben
. . . . .7 小时前
前端测试框架:Vitest
前端
xiaotao1317 小时前
什么是 Tailwind CSS
前端·css·css3
战南诚8 小时前
VUE中,keep-alive组件与钩子函数的生命周期
前端·vue.js
发现一只大呆瓜8 小时前
React-彻底搞懂 Redux:从单向数据流到 useReducer 的终极抉择
前端·react.js·面试
霍理迪8 小时前
Vue的响应式和生命周期
前端·javascript·vue.js
李剑一8 小时前
别再瞎写了!Cesium 模型 360° 环绕,4 套源码全公开,项目直接用
前端