时间轴组件开发:实现灵活的时间范围选择
前言
前端开发中,时间范围选择是一个非常常见的功能需求,无论是数据统计还是订单筛选,都离不开它。虽然 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日期组件清空后的报错,让你的页面不再崩溃