前言
当我们在进行网页开发时,通常需要用到一些日期组件来方便用户选择时间。其中,element 日期组件是一个非常好用的工具。不过,在实际开发中,我们有时需要限制用户选择的时间范围,以保证数据的准确性和合法性。本文将介绍如何使用 element 日期组件的时间范围选择限制功能,帮助开发者更好地应对这一问题。
实现思路
其实实现限制的主要原因是通过 picker-options
属性来限制可选择的时间区间,话不多说,下面介绍几个常用限制时间范围的方法。
1. 只能选择今天及今天之后的日期
<template>
<div>
<el-date-picker v-model="timeDate" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
<script>
export default {
data() {
return {
timeDate: "",
pickerOptions: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7; //只能选择今天及今天之后的日期
//return time.getTime() < Date.now() - 8.64e6; //只能选择今天之后的日期,今天的日期也不能选
}
},
}
},
}
</script>
实现效果
2. 只能选择今天及今天之前的日期
<template>
<div>
<el-date-picker v-model="timeDate" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
<script>
export default {
data() {
return {
timeDate: "",
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now() - 8.64e6; //只能选择今天及今天之前的日期
// return time.getTime() > Date.now() - 8.64e7; //只能选择今天之前的日期,连今天的日期也不能选
}
},
}
},
}
</script>
实现效果
3. 只能选择三个月之前到今天的日期
<template>
<div>
<el-date-picker v-model="timeDate" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
<script>
export default {
data() {
return {
timeDate: "",
pickerOptions: {
disabledDate(time) {
let curDate = (new Date()).getTime();
let three = 90 * 24 * 3600 * 1000;
let threeMonths = curDate - three;
return time.getTime() > Date.now() || time.getTime() < threeMonths;
}
}, //只能选择三个月之前至今天的日期
}
},
}
</script>
实现效果
同理,如果想要调整为 60 天前、30 天前或者 7 天前时间只需要将 “let three = 90 * 24 * 3600 * 1000”
中的 90 修改为需要的时间节点即可。
4. 快捷选择日期区间
<template>
<div>
<el-date-picker v-model="timeDate" type="daterange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期" value-format="yyyy-MM-dd" :picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
<script>
export default {
data() {
return {
timeDate: "",
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
}
},
}
</script>
实现效果
拓展1
需求:结束日期为今天时,时分秒为当前时间,若结束时间不为今天时,时分秒则展示
23:29:59
<template>
<el-date-picker v-model="value1" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
@change="handleDateChange">
</el-date-picker>
</template>
<script>
import moment from "moment";
export default {
data() {
return {
value1: null,
};
},
methods: {
handleDateChange(value) {
if (value && value.length === 2) {
const endDate = value[1];
const today = new Date();
const endDateTime = new Date(endDate);
if (endDateTime.toDateString() === today.toDateString()) {
// 结束时间是今天,时分秒为当前的时间
endDateTime.setHours(today.getHours());
endDateTime.setMinutes(today.getMinutes());
endDateTime.setSeconds(today.getSeconds());
} else {
// 结束时间不是今天,时分秒为23:59:59
endDateTime.setHours(23);
endDateTime.setMinutes(59);
endDateTime.setSeconds(59);
}
this.value1[1] = endDateTime;
// 格式转换
console.log(moment(this.value1[0]).format("YYYY-MM-DD HH:mm:ss"));
console.log(moment(this.value1[1]).format("YYYY-MM-DD HH:mm:ss"));
}
},
},
};
</script>
实现效果
拓展2
需求:动态控制时间选择器的显示和隐藏
<el-date-picker ref="saveDateInput" v-model="dateList" type="datetimerange" range-separator="至" start-placeholder="开始日期"
end-placeholder="结束日期"></el-date-picker>
方法一
this.$refs.time.focus()//隐藏
this.$refs.saveDateInput.focus();//显示
方法二
this.$refs.saveDateInput.pickerVisible = false;//隐藏
this.$refs.saveDateInput.pickerVisible = true;//显示
拓展3
需求:动态控制选择日期的区间
<template>
<div>
<el-select v-model="information.dataType" placeholder="请选择统计维度">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
<el-date-picker ref="saveDateInput" v-model="dateList" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange" @change="handleDateChange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</div>
</template>
<script>
import moment from "moment";
export default {
data() {
return {
options: [
{
value: "1",
label: "分",
},
{
value: "2",
label: "时",
},
{
value: "3",
label: "天",
},
],
information: {
dataType: "1",
},
dateList: [],
};
},
mounted() {},
methods: {
// 日期选择
handleDateChange() {
if (!this.dateList) {
this.dateList = []; // 如果dateList为空,则确保它是一个空数组
return;
}
const { dataType } = this.information;
const startTime = moment(this.dateList[0]);
const endTime = moment(this.dateList[1]);
let isValid = false;
let rangeDescription = "";
if (dataType == "1") {
// 统计维度为"分",判断时间范围是否为30分钟
const diffInMinutes = endTime.diff(startTime, "minutes");
console.log(diffInMinutes, "diffInMinutes");
isValid = diffInMinutes <= 30;
rangeDescription = "请重新选择,时间范围为 30 分钟";
} else if (dataType == "2") {
// 统计维度为"时",判断时间范围是否为48小时
const diffInHours = endTime.diff(startTime, "hours");
console.log(diffInHours, "diffInHours");
isValid = diffInHours <= 48;
rangeDescription = "请重新选择,时间范围为 48 小时";
} else if (dataType == "3") {
// 统计维度为"天",判断时间范围是否为7天
const diffInDays = endTime.diff(startTime, "days");
console.log(diffInDays, "diffInDays");
isValid = diffInDays <= 7;
rangeDescription = "请重新选择,时间范围为 7 天";
}
if (isValid) {
// 时间范围符合要求,可以进行相应的处理
console.log("时间范围符合要求");
this.$refs.saveDateInput.blur();
} else {
// 时间范围不符合要求,进行错误处理
console.log("时间范围不符合要求:" + rangeDescription);
this.$message.warning(rangeDescription);
this.$refs.saveDateInput.focus();
this.dateList = [];
}
},
},
};
</script>
实现效果