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>
相关推荐
go_caipu20 小时前
Vben Admin管理系统集成qiankun微服务(二)
前端·javascript
唐叔在学习20 小时前
insertAdjacentHTML踩坑实录:AI没搞定的问题,我给搞定啦
前端·javascript·html
超绝大帅哥20 小时前
Promise为什么比回调函数更好
前端
幸福小宝20 小时前
uniapp 异型无缝轮播图
前端
wordbaby20 小时前
TanStack Router 实战: 如何设置基础认证和受保护路由
前端
智算菩萨20 小时前
Anthropic Claude 4.5:AI分层编排的革命,成本、速度与能力的新平衡
前端·人工智能
程序员Agions20 小时前
程序员武学修炼手册(三):融会贯通——从写好代码到架构设计
前端·程序员·强化学习
zhouzhouya20 小时前
我和TRAE的这一年:从"看不懂"到"玩得转"的AI学习进化史
前端·程序员·trae
小则又沐风a20 小时前
数据结构->链表篇
前端·html
小王和八蛋20 小时前
前端存储与离线应用实战:Cookie、LocalStorage、PWA 及 Service Worker 核心知识点
前端·javascript