一、前言
在工作中会遇到使用elementUi中的日期选择器el-date-picker,在使用过程中可能会遇到一种情况,就是需要在选择日期的时候增加一下时间范围的要求,比如创建日期不得晚于当前日期,结束日期不得早于开始日期等。如果我们使用的是el-date-picker的type=“daterange” ,那么可以比较好控制开始和结束的选择范围,但是如果是将两个日期拆分成两个使用,那么就需要单独配置一下
主要使用的是el-date-picker的“picker-options”属性。快捷选项需配置picker-options对象中的shortcuts,禁用日期通过 disabledDate 设置,传入函数
二、代码
html部分
<el-date-picker
v-model="startDate"
align="right"
type="date"
placeholder="选择开始日期"
:picker-options="startDisabled">
</el-date-picker>
<el-date-picker
v-model="endDate"
align="right"
type="date"
placeholder="选择结束日期"
:picker-options="endDisabled">
</el-date-picker>
js部分
data() {
return {
//首先data里定义日期选择器关联的两个变量
startDate:"",
endDate:"",
// 然后定义不可选择限制
// 开始日期
startDisabled:{
disabledDate: (time) => {
// 首先判断是否选择了结束时间,如果选择了结束时间,那么开始时间不得晚于结束时间
if(this.endDate) {
return time.getTime() > new Date(this.endDate);
} else {
// 开始日期只能选择当天日期及之前
return time.getTime() >= Date.now();
}
}
},
endDisabled:{
disabledDate: (time) => {
// 首先判断是否选择了开始时间,如果选择了开始时间,那么结束时间不得早于开始时间
if(this.startDate) {
// 如果结束日期和开始日期不可以是同一天,就需要-86400000,如果可以,则不需要
return time.getTime() > new Date(this.startDate);
}
}
}
}
}
效果图如下
上面的代码可以简单实现两个日期选择器实现选择时间范围的情况,①开始日期不得晚于当前日期及不得晚于结束日期②结束日期不得早于开始日期。
如果还有其他的选择日期的要求,也可以在对应的函数里修改。比如要求开始时间可以从当前日期的前一天开始选择
// 此处继续使用上面data中定义的变量
// 开始日期
startDisabled:{
disabledDate: (time) => {
const start = 1 * 24 * 3600 * 1000 // 前一天
if(this.endDate) {
return time.getTime() > new Date(this.endDate)
} else {
return time.getTime() > Date.now() - start;
}
}
},
endDisabled:{
disabledDate: (time) => {
const start = 2 * 24 * 3600 * 1000 // 前一天
if(this.startDate) {
return time.getTime() < new Date(this.startDate);
} else {
return time.getTime() < Date.now() - start
}
}
}
上面提到的是只选择一个时间段提交的情况,可能还会遇到有选择多个时间段的情况
multipleData:[{
startTime: "2023-09-04", endTime: "2023-09-06" }] // 定义一个储存多选时间段的数组
// 开始日期
startDisabled:{
disabledDate: (time) => {
let firstDisabled = ""
let secondDisabled = ""
if(this.endDate) {
firstDisabled = time.getTime() > new Date(this.endDate);
} else {
firstDisabled = time.getTime() >= Date.now();
}
this.multipleData.forEach((item, i) => {
secondDisabled = secondDisabled || (time.getTime() > new Date(item.startTime).getTime() - 86400000 && time.getTime() < new Date(this.endDate))
})
return firstDisabled || secondDisabled
}
},
endDisabled:{
disabledDate: (time) => {
let firstDisabled = ""
let secondDisabled = ""
if(this.startDate) {
firstDisabled = time.getTime() < new Date(this.startDate) - 86400000;
}
this.multipleData.forEach((item, i) => {
secondDisabled = secondDisabled || (time.getTime() > new Date(item.startTime).getTime() - 86400000 && time.getTime() < new Date(item.endTime))
})
return firstDisabled || secondDisabled
}
}
}
效果如下
以上代码只能保证之前选过得不能在选择,但是可以选择之前的日期和之后的日期,也就是会把之前选择的日期包括进去。此时的建议是在提交时间的时候进行单独判断。下面附上一段提交时间是判断时间段是否重复的代码
//data中定义数据
data(){
return {
multipleData: [{
startTime: "2023-09-04", endTime: "2023-09-06" }, {
startTime: "2023-09-08", endTime: "2023-09-16" }, {
startTime: "2023-09-14", endTime: "2023-09-17" }],
}
}
//methods中定义方法
methods:{
judgeTimes() {
let startArr = []
let endArr = []
this.multipleData.forEach(item => {
startArr.push(item.startTime ? new Date(item.startTime).getTime() : "")
endArr.push(item.endTime ? new Date(item.endTime).getTime() : "")
})
let sortArrS = startArr.sort()
let sortArrE = endArr.sort()
let flag = false
for (let i = 0; i < sortArrS.length; i++) {
if (i > 0) {
if (sortArrS[i] <= sortArrE[i - 1]) {
flag = true
}
}
}
if (flag) {
return false
} else {
return true
}
},
submit() {
if (!this.judgeTimes()) {
this.$message.warning("时间段重复")
} else {
this.$message.success("成功")
}
}
}
根据上面函数的返回值判断是否有重复时间段并给出对应提示