组件二次封装-移动端时间段选择

图示

引入(全局注入组件)

1
2
3
import diyDatePicker from "@/components/diy-vant-date-picker";

Vue.component("diyDatePicker", diyDatePicker);

组件使用

1
2
3
4
5
<diy-date-picker
:show-picker="showPicker"
@confirm="filterChange"
@closed="showPicker = false"
/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export default {
data() {
return {
showPicker: false
};
},
methods: {
filterChange(start, end) {
let startTime = start;
let endTime = end;
if (startTime && !endTime) endTime = startTime;
if (!startTime && endTime) startTime = endTime;

this.showPicker = false;

// ...
}
}
};

API

Props

参数说明类型默认值
show-picker是否显示时间选择Booleanfalse
minDate开始日期Datenew Date(2019, 0, 1)
maxDate截止日期Datenew Date(2030, 0, 1)
defaultDate默认日期Datenew Date()

Events

事件说明
confirm点击确定按钮后触发的事件,该方法返回两个参数,开始时间和结束时间
closed点击取消时触发的事件

组件完整代码展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<div class="diyDatePicker-components">
<van-popup
v-model="showPopup"
:style="{top: $STOREX_GET.nav.total + 'px'}"
position="top"
class="picker-popup"
@closed="closed"
>
<div class="popup-header">
<span class="title">选择日期</span>
<span class="cancel-btn" @click="reset">重置</span>
</div>
<div class="picker-range">
<div class="range-info">
<div
class="range-start"
:class="{ active: activeRange == 'start' }"
@click="rangeChange('start')"
>
{{ startDate ? $tools.timeF(startDate, "YYYY年M月D日") :
"请选择开始时间" }}
</div>
<div class="range-separator" />
<div
class="range-end"
:class="{ active: activeRange == 'end' }"
@click="rangeChange('end')"
>
{{ endDate ? $tools.timeF(endDate, "YYYY年M月D日") : "请选择结束时间"
}}
</div>
</div>
</div>
<van-datetime-picker
v-model="currentDate"
type="date"
:show-toolbar="false"
:visible-item-count="3"
:min-date="minDate"
:max-date="maxDate"
:formatter="formatter"
@change="pickerChange"
/>
<div class="picker-btns">
<div class="btn reset-btn" @click="closed">取消</div>
<div class="btn success-btn" @click="confirm">完成</div>
</div>
</van-popup>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
export default {
props: {
minDate: {
type: Date,
default() {
return new Date(2019, 0, 1);
}
},
maxDate: {
type: Date,
default() {
return new Date(2030, 0, 1);
}
},
defaultDate: {
type: Date,
default() {
return new Date();
}
},
showPicker: {
type: Boolean,
default: false
}
},
data() {
return {
activeRange: "",
startDate: "",
endDate: "",
showPopup: false
};
},
watch: {
showPicker(val) {
this.showPopup = val;
}
},
created() {
this.currentDate = this.defaultDate;
},
methods: {
formatter(type, val) {
console.log(type, val);
if (type === "year") {
return `${val}年`;
} else if (type === "month") {
return `${val}月`;
} else if (type === "day") {
return `${val}日`;
}
return val;
},
pickerChange() {
this.activeRange = this.activeRange || "start";
if (this.activeRange == "start") {
this.startDate = this.currentDate;
} else if (this.activeRange == "end") {
this.endDate = this.currentDate;
}
},
rangeChange(type) {
this.activeRange = type;
if (this.activeRange == "start") {
if (this.startDate) {
this.currentDate = this.startDate;
} else {
this.startDate = this.currentDate;
}
} else if (this.activeRange == "end") {
if (this.endDate) {
this.currentDate = this.endDate;
} else {
this.endDate = this.currentDate;
}
}
},
confirm() {
const startDate = this.startDate
? this.$tools.timeF(this.startDate, "YYYY-MM-DD")
: "";
const endDate = this.endDate
? this.$tools.timeF(this.endDate, "YYYY-MM-DD")
: "";
console.log(endDate);
if (startDate && endDate && startDate > endDate) {
this.$toast("开始时间不能大于结束时间");
return false;
}
// if (!startDate && !endDate) {
// this.$toast("请选择开始时间或者结束时间");
// return false;
// }
this.$emit("confirm", startDate, endDate);
},
closed() {
this.$emit("closed");
},
reset() {
this.currentDate = new Date();
this.endDate = this.startDate = "";
this.activeRange = "start";
},
getMonthLastDay(time) {
var date = new Date(time || new Date());
var currentMonth = date.getMonth();
var nextMonth = ++currentMonth;
var nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
var oneDay = 1000 * 60 * 60 * 24;
return this.$tools.timeF(
new Date(nextMonthFirstDay - oneDay),
"YYYY-MM-DD"
);
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
.diyDatePicker-components {
/deep/.van-overlay {
z-index: 100 !important;
}
.picker-popup {
border-radius: 4px 4px 0px 0px;
font-size: 0;
overflow: hidden;
z-index: 9;

.popup-header {
width: 327px;
height: 55px;
margin: 0 auto;
text-align: left;
position: relative;
border-bottom: 1px solid #e2e2e2;

.title {
font-size: 18px;
line-height: 55px;
color: #333333;
}

.cancel-btn {
position: absolute;
display: inline-block;
right: 12px;
top: 16px;
font-size: 13px;
width: 40px;
line-height: 24px;
font-weight: 400;
color: rgba(132, 146, 173, 1);
}
}

.picker-range {
.range-title {
font-size: 14px;
color: rgba(51, 51, 51, 1);
margin: 0 auto;
font-size: 14px;
padding: 16px 0;
}

.range-info {
text-align: center;
margin-top: 12px;
margin-bottom: 32px;

.range-start,
.range-end {
width: 123px;
height: 48px;
font-size: 15px;
line-height: 48px;
display: inline-block;
text-align: center;
color: #7a7a7a;
border-bottom: 1px solid #7a7a7a;
transition: all 0.3s;

&.active {
color: #427bfa;
border-bottom: 1px solid #427bfa;
}
}

.range-separator {
display: inline-block;
width: 26px;
height: 1px;
background-color: #979797;
margin: 0 27px;
}
}
}

.picker-btns {
width: 100%;
text-align: center;
margin-top: 24px;
margin-bottom: 15px;

.btn {
display: inline-block;
width: 166px;
text-align: center;
font-size: 14px;
line-height: normal;
border-radius: 4px;
padding: 10px 0;
border: 1px solid rgba(151, 151, 151, 1);
color: #0b1e53;

&.success-btn {
color: #fff;
margin-left: 15px;
border: 1px solid rgba(151, 151, 151, 1);
background: rgba(66, 123, 250, 1);
}
}
}
}
}