在这篇文章中,我们将展示如何创建一个强大的日期范围选择器,重点介绍了如何从开始日期禁用日期范围。
将使用Vue 3的Composition API和Element Plus库,通过自定义功能来提高用户体验,确保用户在选择日期范围时能够轻松地遵循指定的规则。无论您是构建数据过滤器还是需要日期范围选择的其他用例,这个组件都将满足您的需求。让我们开始吧!
文章末尾有完整代码
文章末尾有完整代码
文章末尾有完整代码
准备工作
首先,确保您的项目中已经安装了Vue 3和Element Plus。如果还没有安装,可以使用以下命令安装:
bash
npm install vue@next
npm install element-plus
接下来,让我们一起创建日期范围选择器组件。
创建日期范围选择器
我们将使用Vue 3的Composition API来创建我们的日期范围选择器。下面是一个简化的示例:
vue
<template>
<el-date-picker
v-model="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
:disabled-date="disabledDate"
@calendar-change="calendarChange"
@visible-change="visibleChange"
/>
</template>
<script setup lang="ts">
import { dayjs } from "element-plus";
import { computed, ref } from "vue";
const date = ref("");
const _startTime = ref();
// ... 省略了其余部分
</script>
在这段代码中,我们使用了Element Plus的el-date-picker
组件来创建日期范围选择器。我们定义了一些属性,如日期格式、占位符、禁用日期的条件以及日期范围变化时的处理函数。
处理日期范围变化
在日期范围选择器中,用户可以选择开始日期和结束日期。为了确保用户选择的日期范围是有效的,我们添加了一个处理函数calendarChange
:
vue
const calendarChange = (v: [string | null, string | null]) => {
if (v?.[0] && v?.[1]) {
if (dayjs(v[0]).isAfter(dayjs(v[1]))) {
_startTime.value = dayjs(v[1]) || undefined;
return;
}
}
_startTime.value = dayjs(v[0]) || undefined;
};
这个函数会检查用户选择的日期范围,如果开始日期晚于结束日期,它会自动将开始日期设置为结束日期,以确保日期范围有效。
处理下拉列表的显示与隐藏
我们还添加了一个visibleChange
函数来处理日期选择器下拉列表的显示与隐藏:
vue
const visibleChange = (visible: boolean) => {
if (!visible) _startTime.value = undefined;
};
当下拉列表出现时,我们保留了一个临时变量_startTime
,但当下拉列表隐藏时,我们将其清空。这有助于确保用户每次打开日期选择器时都有一个干净的状态。
禁用日期
最后,我们定义了一个disabledDate
计算属性来禁用日期的选择条件:
vue
const disabledDate = computed(() => (date: Date) => {
if (!_startTime?.value) {
return dayjs(date).isAfter(dayjs());
}
const diff = dayjs(date).diff(_startTime.value, "day");
return diff < -90 || diff > 90 || dayjs(date).isAfter(dayjs());
});
这个属性会根据用户选择的开始日期禁用一些日期,例如距离开始日期超过90天的日期或今天之后的日期。
结论
通过使用Vue 3的Composition API和Element Plus,我们创建了一个强大的日期范围选择器,并添加了一些自定义功能来提高用户体验。您可以根据项目需求进一步扩展此组件,以满足特定的日期选择需求。希望这篇文章对您有所帮助!
完整代码
vue
<template>
<el-date-picker
v-model="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
type="daterange"
start-placeholder="开始时间"
end-placeholder="结束时间"
:disabled-date="disabledDate"
@calendar-change="calendarChange"
@visible-change="visibleChange"
/>
</template>
<script setup lang="ts">
import { dayjs } from "element-plus";
import { computed, ref } from "vue";
const date = ref("");
// 用于保存日期范围的开始时间
const _startTime = ref();
/**
* 处理日期范围变化的函数
* @param v
*/
const calendarChange = (v: [string | null, string | null]) => {
if (v?.[0] && v?.[1]) {
// 如果开始时间晚于结束时间,则修正开始时间为结束时间
if (dayjs(v[0]).isAfter(dayjs(v[1]))) {
_startTime.value = dayjs(v[1]) || undefined;
return;
}
}
// 更新开始时间为选择的开始日期或清空
_startTime.value = dayjs(v[0]) || undefined;
};
/**
* 当 DateTimePicker 的下拉列表出现/消失时触发
* 出现时为true,隐藏时为false
* 隐藏是 清空保存的临时变量 "_startTime"
* @param visible
*/
const visibleChange = (visible: boolean) => {
if (!visible) _startTime.value = undefined;
};
/**
* 根据日期判断是否禁用日期选择的函数
* @param date 要检查的日期
* @returns 是否禁用该日期
*/
const disabledDate = computed(() => (date: Date) => {
if (!_startTime?.value) {
// 如果没有选择开始时间,则禁用今天之后的所有日期
return dayjs(date).isAfter(dayjs());
}
// 计算日期与开始日期的天数差
// const diff = dayjs(date).diff(_startTime.value, "month");
// // 禁用条件:日期距离开始日期超过3个月,或者日期在今天之后
// return diff < -3 || diff > 3 || dayjs(date).isAfter(dayjs());
// 计算日期与开始日期的天数差
const diff = dayjs(date).diff(_startTime.value, "day");
// 禁用条件:日期距离开始日期超过90天,或者日期在今天之后
return diff < -90 || diff > 90 || dayjs(date).isAfter(dayjs());
});
</script>