在做后台管理系统的时候,搜索条件经常会有日期范围选择.ElementPlus日期范围组件选择的日期值返回的是一个数组.
但是提交的时候,后台有时候是分成两个字段进行接收.
封装一个通用的 日期范围组件(基于 Element Plus 的
),
让前端使用时简单(用数组表示),
但提交给后端时,能自动映射为两个独立字段:startTime 和 endTime。
核心目标
组件内部 使用 v-model 绑定一个日期数组([开始时间, 结束时间]);
对外暴露 时,可以自动:
- 发出完整的数组;
- 或者同时发出 { startTime, endTime } 两个字段;
- 支持在父组件中自定义字段名(例如后端是 begin_date / end_date)。
封装思路
我们可以封装一个组件,比如叫 DateRangePicker.vue
// DateRangePicker.vue 组件
<template>
<el-date-picker
v-model="innerValue"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
@change="handleChange"
style="width: 100%"
/>
</template>
<script setup>
import { computed, ref, watch } from "vue";
const props = defineProps({
modelValue: {
type: Array,
default: () => [],
},
startKey: {
type: String,
default: "startTime",
},
endKey: {
type: String,
default: "endTime",
},
});
const emits = defineEmits(["update:modelValue", "update:fields", "change"]);
// 内部绑定值
const innerValue = ref(props.modelValue);
// 监听外部更新
watch(
() => props.modelValue,
(val) => {
innerValue.value = val;
}
);
// 当值变化时,发出两个不同字段
const handleChange = (val) => {
emits("update:modelValue", val);
if (Array.isArray(val) && val.length === 2) {
emits("update:fields", {
[props.startKey]: val[0],
[props.endKey]: val[1],
});
} else {
emits("update:fields", {
[props.startKey]: "",
[props.endKey]: "",
});
}
emits("change", val);
};
</script>
这个组件做了什么?
| 功能 | 说明 |
|---|---|
| v-model 数组绑定 | 让父组件用 [start, end] 来操作 |
| 自动转换成对象 | 通过 @update:fields 发出 { startTime, endTime } |
| 字段名可配置 | 父组件可用 startKey="beginDate" endKey="endDate" 来适配后端字段 |
父组件使用
<template>
<div style="width: 300px; margin: 20px;">
<DateRangePicker
v-model="range"
@update:fields="handleDateFields"
startKey="beginDate"
endKey="endDate"
/>
<div style="margin-top: 20px;">
<p>当前日期数组: {{ range }}</p>
<p>提交给后端的对象: {{ dateFields }}</p>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import DateRangePicker from "./DateRangePicker.vue";
const range = ref(["2025-01-01", "2025-01-15"]);
const dateFields = ref({ beginDate: "", endDate: "" });
const handleDateFields = (val) => {
dateFields.value = val;
};
</script>

Comments
请在后台配置评论类型和相关的值。