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>
相关推荐
一颗努力的大土豆2 小时前
关于解决switch开关属性中active-value=“1“为数值形失败的问题
javascript·vue.js·elementui
卷Java2 小时前
WXML 编译错误修复总结
xml·java·前端·微信小程序·uni-app·webview
Liu.7742 小时前
vue3 中实现 Element Plus 表格合并
javascript·vue.js·elementui
SevgiliD2 小时前
解决使用 fixed固定列时el-table导致纵向滚动条问题
前端·vue.js·elementui
天蓝色的鱼鱼2 小时前
🚀 告别 Electron 的臃肿:用 Tauri 打造「轻如鸿毛」的桌面应用
前端
余大侠在劈柴2 小时前
go语言学习记录9.23
开发语言·前端·学习·golang·go
bitbitDown3 小时前
忍了一年多,我终于对i18n下手了
前端·javascript·架构
JarvanMo3 小时前
我尝试了Appwrite, Supabase和 Firebase Databases
前端·后端
Hilaku3 小时前
前端的单元测试,大部分都是在自欺欺人
前端·javascript·单元测试