431 lines
13 KiB
Vue
431 lines
13 KiB
Vue
<template>
|
|
<uniPopup ref="popup" type="bottom">
|
|
<view class="tpf-time-range-section">
|
|
<view
|
|
class="tpf-time-range-title-section flex flex-align-center flex-pack-justify"
|
|
>
|
|
<text
|
|
class="tpf-time-range-title-txt tpf-time-range-cancel"
|
|
@tap="closePopup('cancel')"
|
|
>取消</text
|
|
>
|
|
<text class="tpf-time-range-title-txt tpf-time-range-title"
|
|
>时间范围选择</text
|
|
>
|
|
<text
|
|
class="tpf-time-range-title-txt tpf-time-range-sure"
|
|
@tap="closePopup('sure')"
|
|
>确定</text
|
|
>
|
|
</view>
|
|
<view
|
|
class="tpf-time-range-main flex flex-l flex-align-center flex-pack-justify"
|
|
>
|
|
<view class="tpf-time-range-item flex flex-v flex-align-center">
|
|
<text class="tpf-start-time">开始时间</text>
|
|
<picker-view
|
|
class="flex-1 tpf-picker-view"
|
|
:value="startDefaultTimeArr"
|
|
indicator-style="height: 50px;"
|
|
@change="startTimeChange"
|
|
>
|
|
<picker-view-column>
|
|
<view
|
|
class="tpf-time-range-picker-item flex flex-align-center flex-pack-center"
|
|
v-for="(item, index) in createTimeRange.hours"
|
|
:key="index"
|
|
>{{ item }}</view
|
|
>
|
|
</picker-view-column>
|
|
<picker-view-column>
|
|
<view
|
|
class="tpf-time-range-picker-item flex flex-align-center flex-pack-center"
|
|
v-for="(item, index) in createTimeRange.startMinutes"
|
|
:key="index"
|
|
>{{ item }}</view
|
|
>
|
|
</picker-view-column>
|
|
</picker-view>
|
|
</view>
|
|
<text class="tpf-time-divide"> - </text>
|
|
<view class="tpf-time-range-item flex flex-v flex-align-center">
|
|
<text class="tpf-start-time">结束时间</text>
|
|
<picker-view
|
|
class="flex-1 tpf-picker-view"
|
|
:value="endDefaultTimeArr"
|
|
indicator-style="height: 50px;"
|
|
@change="endTimeChange"
|
|
>
|
|
<picker-view-column>
|
|
<view
|
|
class="tpf-time-range-picker-item flex flex-align-center flex-pack-center"
|
|
v-for="(item, index) in createTimeRange.hours"
|
|
:key="index"
|
|
>{{ item }}</view
|
|
>
|
|
</picker-view-column>
|
|
<picker-view-column>
|
|
<view
|
|
class="tpf-time-range-picker-item flex flex-align-center flex-pack-center"
|
|
v-for="(item, index) in createTimeRange.endMinutes"
|
|
:key="index"
|
|
>{{ item }}</view
|
|
>
|
|
</picker-view-column>
|
|
</picker-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uniPopup>
|
|
</template>
|
|
|
|
<script>
|
|
/**
|
|
* TimeRange 时间范围选择
|
|
* @description 对时间(时、分)区间进行选择,限制选择范围
|
|
* @property {string} startTime 定义开始时间
|
|
* @property {string} startDefaultTime 定义开始默认时间
|
|
* @property {string} endTime 定义结束时间
|
|
* @property {string} endDefaultTime 定义结束默认时间
|
|
* @event {Function()} name
|
|
*/
|
|
|
|
import uniPopup from "../uni-popup/uni-popup.vue";
|
|
// import { uniPopup } from "@dcloudio/uni-ui";
|
|
export default {
|
|
name: "TpfTimeRange",
|
|
components: {
|
|
uniPopup,
|
|
},
|
|
props: {
|
|
// 开始时间
|
|
startTime: {
|
|
type: String,
|
|
default: "00:00",
|
|
validator: (value) => {
|
|
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
|
|
},
|
|
},
|
|
// 开始默认时间
|
|
startDefaultTime: {
|
|
type: String,
|
|
// #ifdef MP-WEIXIN
|
|
default: "00:00",
|
|
// #endif
|
|
// #ifndef MP-WEIXIN
|
|
default() {
|
|
return this.startTime;
|
|
},
|
|
// #endif
|
|
|
|
validator: (value) => {
|
|
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
|
|
},
|
|
},
|
|
// 结束时间
|
|
endTime: {
|
|
type: String,
|
|
default: "23:59",
|
|
validator: (value) => {
|
|
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
|
|
},
|
|
},
|
|
// 结束默认时间
|
|
endDefaultTime: {
|
|
type: String,
|
|
// #ifdef MP-WEIXIN
|
|
default: "23:59",
|
|
// #endif
|
|
// #ifndef MP-WEIXIN
|
|
default() {
|
|
return this.endTime;
|
|
},
|
|
// #endif
|
|
validator: (value) => {
|
|
return /(((2[0-3])|([0-1][0-9])):[0-5][0-9])|24:00/.test(value);
|
|
},
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
startDefaultTimeArr: [0, 0],
|
|
endDefaultTimeArr: [0, 0],
|
|
};
|
|
},
|
|
methods: {
|
|
startTimeChange(e) {
|
|
this.startDefaultTimeArr = e.detail.value;
|
|
if (this.compareTwoTimeRange(e.detail.value, this.endDefaultTimeArr))
|
|
this.endDefaultTimeArr = e.detail.value;
|
|
},
|
|
endTimeChange(e) {
|
|
this.endDefaultTimeArr = e.detail.value;
|
|
if (this.compareTwoTimeRange(this.startDefaultTimeArr, e.detail.value))
|
|
this.startDefaultTimeArr = e.detail.value;
|
|
},
|
|
open() {
|
|
this.$refs.popup.open();
|
|
},
|
|
closePopup(action = "") {
|
|
if (
|
|
this.compareTwoTimeRange(
|
|
this.startDefaultTimeArr,
|
|
this.endDefaultTimeArr
|
|
)
|
|
) {
|
|
uni.showToast({
|
|
title: "开始时间不能大于结束时间",
|
|
icon: "none",
|
|
});
|
|
return false;
|
|
}
|
|
let startTime =
|
|
this.createTimeRange.hours[this.startDefaultTimeArr[0]] +
|
|
":" +
|
|
this.createTimeRange.startMinutes[this.startDefaultTimeArr[1]];
|
|
let endTime =
|
|
this.createTimeRange.hours[this.endDefaultTimeArr[0]] +
|
|
":" +
|
|
this.createTimeRange.endMinutes[this.endDefaultTimeArr[1]];
|
|
this.$emit("timeRange", [startTime, endTime]);
|
|
this.$refs.popup.close();
|
|
},
|
|
compareTwoTimeRange(arr1 = [], arr2 = []) {
|
|
if (arr1[0] > arr2[0] || (arr1[0] == arr2[0] && arr1[1] > arr2[1]))
|
|
return true;
|
|
return false;
|
|
},
|
|
},
|
|
beforeCreate() {
|
|
// 初始化小时
|
|
let hour = [],
|
|
minute = [];
|
|
for (let h = 0; h <= 24; h++) {
|
|
hour.push(h < 10 ? "0" + h : h + "");
|
|
}
|
|
for (let m = 0; m < 60; m++) {
|
|
minute.push(m < 10 ? "0" + m : m + "");
|
|
}
|
|
this.timeRange = { hour, minute };
|
|
},
|
|
created() {},
|
|
computed: {
|
|
createTimeRange() {
|
|
let { startTime, startDefaultTime, endTime, endDefaultTime } =
|
|
this.timeRangeDateChange;
|
|
let startTimeArr = startTime.split(":"),
|
|
endTimeArr = endTime.split(":");
|
|
let hours = this.timeRange.hour.slice(
|
|
this.timeRange.hour.findIndex((item) => item == startTimeArr[0]),
|
|
this.timeRange.hour.findIndex((item) => item == endTimeArr[0]) + 1
|
|
);
|
|
|
|
let startMinutes = null;
|
|
if (startTimeArr[0] == endTimeArr[0]) {
|
|
startMinutes = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1]),
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) + 1
|
|
);
|
|
} else {
|
|
if (this.startDefaultTimeArr[0] == 0) {
|
|
startMinutes = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1])
|
|
);
|
|
} else if (this.startDefaultTimeArr[0] == hours.length - 1) {
|
|
startMinutes = this.timeRange.minute.slice(
|
|
0,
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) + 1
|
|
);
|
|
} else {
|
|
startMinutes = this.timeRange.minute; // 完整数据
|
|
}
|
|
}
|
|
let endMinutes = null;
|
|
if (startTimeArr[0] == endTimeArr[0]) {
|
|
endMinutes = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1]),
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) + 1
|
|
);
|
|
} else {
|
|
if (this.endDefaultTimeArr[0] == 0) {
|
|
endMinutes = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1])
|
|
);
|
|
} else if (this.endDefaultTimeArr[0] == hours.length - 1) {
|
|
endMinutes = this.timeRange.minute.slice(
|
|
0,
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) + 1
|
|
);
|
|
} else {
|
|
endMinutes = this.timeRange.minute; // 完整数据
|
|
}
|
|
}
|
|
return {
|
|
hours,
|
|
startMinutes,
|
|
endMinutes,
|
|
};
|
|
},
|
|
// 用于监听属性的变化
|
|
timeRangeDateChange() {
|
|
let { startTime, startDefaultTime, endTime, endDefaultTime } = this;
|
|
startTime = startTime < endTime ? startTime : endTime;
|
|
startDefaultTime =
|
|
startDefaultTime >= startTime && startDefaultTime <= endTime
|
|
? startDefaultTime
|
|
: startTime;
|
|
endDefaultTime =
|
|
endDefaultTime >= startTime &&
|
|
endDefaultTime <= endTime &&
|
|
endDefaultTime >= startDefaultTime
|
|
? endDefaultTime
|
|
: startDefaultTime;
|
|
return {
|
|
startTime,
|
|
startDefaultTime,
|
|
endTime,
|
|
endDefaultTime,
|
|
};
|
|
},
|
|
},
|
|
watch: {
|
|
timeRangeDateChange: {
|
|
handler(newVal, oldVal) {
|
|
let { startTime, startDefaultTime, endTime, endDefaultTime } = newVal;
|
|
let startTimeArr = startTime.split(":"),
|
|
endTimeArr = endTime.split(":");
|
|
let startDefaultTimeArr = startDefaultTime.split(":"),
|
|
endDefaultTimeArr = endDefaultTime.split(":");
|
|
|
|
let hours = this.timeRange.hour.slice(
|
|
this.timeRange.hour.findIndex((item) => item == startTimeArr[0]),
|
|
this.timeRange.hour.findIndex((item) => item == endTimeArr[0]) + 1
|
|
);
|
|
|
|
this.$set(
|
|
this.startDefaultTimeArr,
|
|
0,
|
|
hours.includes(startDefaultTimeArr[0])
|
|
? hours.findIndex((item) => item == startDefaultTimeArr[0])
|
|
: 0
|
|
);
|
|
this.$set(
|
|
this.endDefaultTimeArr,
|
|
0,
|
|
hours.includes(endDefaultTimeArr[0])
|
|
? hours.findIndex((item) => item == endDefaultTimeArr[0])
|
|
: this.startDefaultTimeArr[0]
|
|
);
|
|
|
|
let startMinute = null,
|
|
endMinute = null;
|
|
if (startTimeArr[0] == endTimeArr[0]) {
|
|
startMinute = endMinute = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1]),
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) + 1
|
|
);
|
|
} else {
|
|
if (startDefaultTime.split(":")[0] == startTimeArr[0]) {
|
|
startMinute = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1])
|
|
);
|
|
} else if (startDefaultTime.split(":")[0] == endTimeArr[0]) {
|
|
startMinute = this.timeRange.minute.slice(
|
|
0,
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) +
|
|
1
|
|
);
|
|
} else {
|
|
startMinute = this.timeRange.minute;
|
|
}
|
|
if (endDefaultTime.split(":")[0] == startTimeArr[0]) {
|
|
endMinute = this.timeRange.minute.slice(
|
|
this.timeRange.minute.findIndex((item) => item == startTimeArr[1])
|
|
);
|
|
} else if (endDefaultTime.split(":")[0] == endTimeArr[0]) {
|
|
endMinute = this.timeRange.minute.slice(
|
|
0,
|
|
this.timeRange.minute.findIndex((item) => item == endTimeArr[1]) +
|
|
1
|
|
);
|
|
} else {
|
|
endMinute = this.timeRange.minute;
|
|
}
|
|
}
|
|
this.$set(
|
|
this.startDefaultTimeArr,
|
|
1,
|
|
startMinute.includes(startDefaultTimeArr[1])
|
|
? startMinute.findIndex((item) => item == startDefaultTimeArr[1])
|
|
: 0
|
|
);
|
|
this.$set(
|
|
this.endDefaultTimeArr,
|
|
1,
|
|
endMinute.includes(endDefaultTimeArr[1])
|
|
? endMinute.findIndex((item) => item == endDefaultTimeArr[1])
|
|
: this.startDefaultTimeArr[1]
|
|
);
|
|
},
|
|
deep: true, // 深度监听
|
|
immediate: true, // 初始化立即执行
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.flex {
|
|
display: flex;
|
|
}
|
|
.flex-v {
|
|
flex-direction: column;
|
|
}
|
|
.flex-wrap {
|
|
flex-wrap: wrap;
|
|
}
|
|
.flex-row-wrap {
|
|
flex-flow: row wrap;
|
|
}
|
|
.flex-1 {
|
|
flex: 1;
|
|
}
|
|
.flex-align-center {
|
|
align-items: center;
|
|
}
|
|
.flex-pack-center {
|
|
justify-content: center;
|
|
}
|
|
.flex-pack-justify {
|
|
justify-content: space-between;
|
|
}
|
|
.flex-pack-around {
|
|
justify-content: space-around;
|
|
}
|
|
.tpf-time-range-section {
|
|
background-color: #fff;
|
|
}
|
|
.tpf-time-range-title-section {
|
|
padding: 20rpx;
|
|
border-bottom: 1px #f2f2f2 solid;
|
|
}
|
|
.tpf-time-range-title-txt {
|
|
font-size: 28rpx;
|
|
}
|
|
.tpf-time-range-title {
|
|
font-size: 32rpx;
|
|
}
|
|
.tpf-time-range-main {
|
|
padding: 0 20rpx 20rpx;
|
|
}
|
|
.tpf-time-range-item {
|
|
height: 400rpx;
|
|
width: 300rpx;
|
|
}
|
|
.tpf-start-time {
|
|
padding: 20rpx 0;
|
|
}
|
|
.tpf-picker-view {
|
|
width: 280rpx;
|
|
}
|
|
</style> |