vue组件 – 实现一种小时级时间段选择
效果
操作大概是选择一个开始时间和一个结束时间(从左往右选是选择,从右往左是取消),排除已选后计算他们总的时间段。
代码:
- 单个组件页面
<template>
<div>
<div class="hours-container">
<div v-for="(item, index) in hours" :key="index" class="hours-item">
<div class="hours-item-header">{
{
compItem(item) }}</div>
<div class="hours-item-value">
<div
:class="compClass(2 * item)"
@click="handleClick(2 * item)"
@mouseover="handleHover(2 * item)"
></div>
<div
:class="compClass(2 * item + 1)"
@click="handleClick(2 * item + 1)"
@mouseover="handleHover(2 * item + 1)"
></div>
</div>
</div>
</div>
<div class="tips">{
{
tips }}</div>
</div>
</template>
<script>
/*
* @Description 为了实现24小时区间选择,若有星期的需求直接看 TimeRangeList组件
* @Author dengkangning
* @Date 2020年11月18日 16:33:19
*/
export default {
model: {
prop: "sendTimeList",
},
props: {
sendTimeList: {
required: true,
default: []
},
readonly: {
type: Boolean,
default: false
}
},
watch: {
timeRangeList: function (value) {
this.$emit('change', value);
this.$parent.$emit("el.form.change");// 触发父组件的校验规则
},
sendTimeList:{
handler () {
this.transformedIndex();
},
deep:true
}
},
computed: {
},
data() {
return {
hours: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22],// 选项
selectStart: false,// 开始
startIndex: '',// 开始下标
timeRangeList: [],// 选择的时间段
timeRangeListIndex: [],// 选中的下标
tempRangeIndex: [],// 预选下标
tips: '向右选中,向左取消选择'
}
},
methods: {
// 时间区间转换成下标区间
transformedIndex() {
this.timeRangeListIndex = [];
this.timeRangeList = this.sendTimeList;
this.timeRangeList.forEach(element => {
const [startTime, endTime] = element.match(/\d+\:\d+/g);
if (startTime && endTime) {
let [startHour, startMin] = startTime.split(':');
let [endHour, endMin] = endTime.split(':');
if (startHour && startMin && endHour && endMin) {
let startNum, endNum;
if (startMin === '00') {
startNum = 2 * parseInt(startHour);
} else {
startNum = 2 * parseInt(startHour) + 1;
}
if (endMin === '00') {
endNum = 2 * parseInt(endHour) - 1;
} else {
endNum = 2 * parseInt(endHour);
}
while (endNum >= startNum) {
this.timeRangeListIndex.push(startNum);
startNum++;
}
} else {
this.$message.error("时间段格式不正确");
}
} else {
this.$message.error("没有拿到开始时间或结束时间或者时间段格式不对");
}
});
this.tips = this.timeRangeList && this.timeRangeList.length > 0 ? this.timeRangeList : '向右选中,向左取消选择';
},
// 下标区间转换成时间区间
transformedSection() {
this.timeRangeList = [];
let startTime = '', endTime = '', len = this.hours.length;
for (let index = this.hours[0] * 2; index < 2 * (len + 1); index++) {
if (this.timeRangeListIndex.indexOf(index) > -1) {
if (startTime) {
// 如果有开始时间,直接确定结束时间
let endHour = Math.floor((index + 1) / 2);
let endMin = (index + 1) % 2 === 0 ? "00" : "30";
endTime = `${
endHour < 10 ? '0' + endHour : endHour}:${
endMin}`;
} else {
// 没有开始时间,确定当前点为开始时间
let startHour = Math.floor(index / 2);
let startMin = index % 2 === 0 ? "00" : "30";
startTime = `${
startHour < 10 ? '0' + startHour : startHour}:${
startMin}`;
}
if (index === 2 * this.hours.length + 1) {
// 如果是最后一格,直接结束
endTime = `${
Math.floor((index + 1) / 2)}:00`;
this.timeRangeList.push(`${
startTime ? startTime : "23:30"}-${
endTime}`);
startTime = '';
endTime = '';
}
} else {
// 若这个点不在选择区间,确定一个时间段
if (startTime && endTime) {
this.timeRangeList.push(`${
startTime}-${
endTime}`);
startTime = '';
endTime = '';
} else if (startTime && !endTime) {
// 这里可能只选半个小时
let endHour = Math.floor(index / 2);
let endMin = index % 2 === 0 ? "00" : "30";
endTime = `${
endHour < 10 ? '0' + endHour : endHour}:${