前言
前端开发中,时间范围选择是一个非常常见的功能需求,无论是数据统计还是订单筛选,都离不开它。虽然 element 组件库提供的基础日期选择器能够满足大部分常规需求,但当项目出现 「动态时间推移」「时间间隔自定义」 等定制化需求时,原生组件便显得捉襟见肘。本文将实现自定义的时间范围选择组件,不仅支持自定义时间区间的选择,还能根据用户设置的时间间隔,实现向前、向后推移时间范围的交互功能。
一、完整代码
<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 日期组件使用技巧:时间范围选择限制
⭐ element日期选择器掌控时间范围,更好地满足你的需求
⭐ element日期组件新玩法:只选小时或小时、分钟,让时间更精准
⭐ 解决element日期组件清空后的报错,让你的页面不再崩溃