element-ui日期范围组件之改造
element-ui现成的日期范围组件
element-ui提供了日期范围组件,方便直接使用,但交互体验被产品喷,甚至被后端喷(手动捂脸),主要表现为:
- 开始结束日期每次得重新选择
- 区间跨度大的时候选择不方便
- v-model绑定的是一个数组[startDate, endDate],和input/select这些格格不入,提交表单时得额外处理数据

平常就是这么用的:绑定一个range数组,不能直接绑定表单的startDate/endDate
<el-form-item class="c2" label="营业期限" prop="termDateRange" required>
<el-date-picker
v-model="form.termDateRange"
style="width: 100%"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
/>
</el-form-item>
最后将range转为startDate/endDate
const range = this.form.termDateRange
this.form.termStartDate = range ? range[0] : ''
this.form.termEndDate = range ? range[1] : ''
所以,前端也看他不爽
自己封装的日期范围组件
于是就想到封装一个日期范围组件,
- 由两个日期选择器合成,开始日期、结束日期分开选择但相互关联,不会出现结束日期早于开始日期
- 单个的日期选择可以先选择年份,再选择月份和日期,解决了日期跨度大选择不便
- 不用和一个数组绑定了
上代码
<template>
<div class="flex">
<el-form-item class="fill" :prop="startProp" :rules="rules">
<el-date-picker
v-model="form[startProp]"
style="width: 100%"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
@change="onStartChange"
/>
</el-form-item>
<span class="margin-sm-lr">-</span>
<el-form-item class="fill" :prop="endProp" :rules="rules">
<el-date-picker
v-model="form[endProp]"
style="width: 100%"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
@change="onEndChange"
/>
</el-form-item>
</div>
</template>
import moment from 'moment'
export default {
name: 'VDateRange',
props: {
// 表单中开始日期的字段
startProp: {
type: String,
default: ''
},
// 表单中结束日期的字段
endProp: {
type: String,
default: ''
},
// 是否必填项
required: {
type: Boolean,
default: false
},
form: {
type: Object,
default: () => {}
}
},
computed: {
rules () {
return { required: this.required, message: '必填项' }
}
},
methods: {
onStartChange (start) {
// 开始日期晚于结束日期时,结束日期自动设置为开始日期
const isAfter = moment(start).isAfter(this.form[this.endProp])
if (isAfter) {
this.form[this.endProp] = start
}
},
onEndChange (end) {
// 结束日期早于开始日期时,开始日期自动设置为结束日期
const isBefore = moment(end).isBefore(this.form[this.startProp])
if (isBefore) {
this.form[this.startProp] = end
}
}
}
}
像这样使用
<el-form ref="form" class="flex flex-wrap space-between cols-5" :model="form" label-position="top">
<el-form-item label="日期区间" class="c2" required>
<VDateRange start-prop="start" end-prop="end" :form="form" required />
</el-form-item>
</el-form>


欢迎提出改进意见

浙公网安备 33010602011771号