前言
前端开发中,时间范围选择是一个非常常见的功能需求,无论是数据统计还是订单筛选,都离不开它。虽然 element 组件库提供的基础日期选择器能够满足大部分常规需求,但当项目出现 「动态时间推移」「时间间隔自定义」 等定制化需求时,原生组件便显得捉襟见肘。本文将实现自定义的时间范围选择组件,不仅支持自定义时间区间的选择,还能根据用户设置的时间间隔,实现向前、向后推移时间范围的交互功能。
一、完整代码
html
<template>
<div class="timeline">
<div>
<el-date-picker v-model="dateData" :picker-options="pickerOptions" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="defaultTime" @change="timeChange"> </el-date-picker>
</div>
<div>
<el-select v-model="interval" placeholder="请选择间隔时间">
<el-option v-for="item in optionsInterval" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</div>
<div>
<el-tooltip class="item" effect="dark" :content="'时间向前' + interval + '小时'" placement="top-start">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="63px" height="40px" class="leftArrow" @click="front">
<g transform="matrix(1 0 0 1 -562 -494 )">
<path d="M 593 529.4 L 609 514 L 593 498.6 L 593 529.4 Z " fill-rule="nonzero" fill="#70b603" stroke="none" />
<path d="M 566 514 L 597 514 " stroke-width="8" stroke="#70b603" fill="none" />
</g>
</svg>
</el-tooltip>
<el-tooltip class="item" effect="dark" :content="'时间向后' + interval + '小时'" lacement="top-start">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="63px" height="40px" @click="offspring">
<g transform="matrix(1 0 0 1 -562 -494 )">
<path d="M 593 529.4 L 609 514 L 593 498.6 L 593 529.4 Z " fill-rule="nonzero" fill="#70b603" stroke="none" />
<path d="M 566 514 L 597 514 " stroke-width="8" stroke="#70b603" fill="none" />
</g>
</svg>
</el-tooltip>
</div>
</div>
</template>
<script>
export default {
data() {
const initialDateData = ["2022-02-01 15:20:30", "2022-02-04 12:30:00"]; // 初始化初始日期范围
return {
defaultTime: ["00:00:00", "23:59:59"],
dateData: [...initialDateData], // 当前日期范围,初始值为初始日期范围的副本
initialDateData, // 存储初始日期范围,用于后续比较
currentDateData: [...initialDateData], // 当前操作的日期范围,初始值为初始日期范围的副本
pickerOptions: {
disabledDate: (time) => {
const start = new Date(this.initialDateData[0]).getTime();
const end = new Date(this.initialDateData[1]).getTime();
return time.getTime() < start || time.getTime() > end;
},
},
interval: "1",
optionsInterval: [
{
value: "1",
label: "1小时",
},
{
value: "3",
label: "3小时",
},
{
value: "5",
label: "5小时",
},
{
value: "7",
label: "7小时",
},
],
};
},
methods: {
// 日期范围选择变化时的回调函数
timeChange(newValue) {
// 更新当前操作的日期范围为新选择的日期范围
this.currentDateData = newValue;
},
// 向前操作的方法
front() {
// 获取当前操作日期范围的结束时间
const currentEndTime = new Date(this.currentDateData[1]);
// 计算新的结束时间,通过当前结束时间减去所选间隔小时数
const newEndTime = new Date(currentEndTime.getTime() - parseInt(this.interval) * 60 * 60 * 1000);
// 获取初始日期范围的开始时间
const initialStartTime = new Date(this.initialDateData[0]);
// 检查新的结束时间是否大于等于初始开始时间
if (newEndTime >= initialStartTime) {
// 计算新的开始时间,通过新的结束时间减去所选间隔小时数
const newStartTime = new Date(newEndTime.getTime() - parseInt(this.interval) * 60 * 60 * 1000);
// 更新当前操作的日期范围,确保新的开始时间不小于初始开始时间
this.currentDateData = [this.formatDate(newStartTime >= initialStartTime ? newStartTime : initialStartTime), this.formatDate(newEndTime)];
// 同步更新显示的日期范围
this.dateData = [...this.currentDateData];
} else {
// 若超出范围,给出警告提示
this.$message.warning("向前操作超出了初始时间范围!");
}
},
// 向后操作的方法
offspring() {
// 获取当前操作日期范围的开始时间
const currentStartTime = new Date(this.currentDateData[0]);
// 计算新的开始时间,通过当前开始时间加上所选间隔小时数
const newStartTime = new Date(currentStartTime.getTime() + parseInt(this.interval) * 60 * 60 * 1000);
// 获取初始日期范围的结束时间
const initialEndTime = new Date(this.initialDateData[1]);
// 检查新的开始时间是否小于等于初始结束时间
if (newStartTime <= initialEndTime) {
// 计算新的结束时间,通过新的开始时间加上所选间隔小时数
const newEndTime = new Date(newStartTime.getTime() + parseInt(this.interval) * 60 * 60 * 1000);
// 更新当前操作的日期范围,确保新的结束时间不大于初始结束时间
this.currentDateData = [this.formatDate(newStartTime), this.formatDate(newEndTime <= initialEndTime ? newEndTime : initialEndTime)];
// 同步更新显示的日期范围
this.dateData = [...this.currentDateData];
} else {
// 若超出范围,给出警告提示
this.$message.warning("向后操作超出了初始时间范围!");
}
},
// 日期格式化方法,将 Date 对象转换为指定格式的字符串
formatDate(date) {
// 获取年份
const year = date.getFullYear();
// 获取月份、日、小时、分钟、秒并补零
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
// 返回格式化后的日期字符串
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
},
};
</script>
<style scoped>
.timeline {
padding: 20px;
display: flex;
}
.timeline div {
margin-right: 5px;
}
.leftArrow {
transform: rotate(180deg);
}
svg {
cursor: pointer;
}
</style>
二、实现思路
-
模板部分
<template>
包含日期范围选择器,一个间隔时间选择下拉框,两个
el-tooltip
组件,分别包含一个SVG
图标,用于时间向前和向后操作,分别绑定了front
和offspring
方法; -
数据部分
data
变量 描述 defaultTime 设置日期选择器的默认时间范围为一天(从 00:00:00 到 23:59:59) dateData 当前显示的日期范围,初始值为 initialDateData 的副本 initialDateData 存储初始日期范围,用于限制可选日期范围 currentDateData 当前操作的日期范围,初始值为 initialDateData 的副本 pickerOptions 日期选择器的选项,通过 disabledDate 方法限制可选日期范围在 initialDateData 之内 interval 当前选择的间隔时间,默认值为 '1' optionsInterval 间隔时间选择下拉框的选项数组 -
方法部分
methods
方法名 描述 timeChange 当日期范围选择变化时的回调函数,更新 currentDateData 为新选择的日期范围 front 时间向前操作的方法,计算新的结束时间和开始时间,检查是否在初始时间范围内,更新 currentDateData 和 dateData,若超出范围则给出警告提示 offspring 时间向后操作的方法,计算新的开始时间和结束时间,检查是否在初始时间范围内,更新 currentDateData 和 dateData,若超出范围则给出警告提示 formatDate 日期格式化方法,将 Date 对象转换为指定格式的字符串 -
样式部分
style
定义了
.timeline
类的样式,设置宽度、内边距、显示方式和子元素的间距。定义了
.leftArrow
类的样式,将SVG
图标旋转180
度。定义了
svg
元素的样式,设置鼠标指针为指针样式。
通过以上实现思路,就可以满足日期范围选择、间隔时间选择以及时间向前和向后操作的功能,并在操作过程中进行时间范围的限制和提示。
三、实现效果

相关推荐
⭐ element日期选择器掌控时间范围,更好地满足你的需求