element UI el-date-picker 年月日切换组件
# Element UI el-date-picker 年月日切换组件
组件特点:
- 切换elementUI el-date-picker 的类型的按钮,并且页面显示不出问题
- 有change事件抛出 有 类型变量.sync
<template>
<div class="day-selector-comp">
<div class='select-button-list'>
<div v-for='type in timeTypeList'
:key="type.value"
class="select-button"
:class="{active: timeType === type.value}"
@click="handleTimeTypeChanged(type.value)">
{{ type.label }}
</div>
</div>
<div class='selectPicker'>
<div v-for='type in timeTypeList' :key="type.value">
<el-date-picker
ref="datePicker"
v-if="timeType === type.value"
clearable
v-model="timeModel"
:type="type.value"
v-on="$listeners"
>
</el-date-picker>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'daySelector',
props: {
time: {
type: Date,
default: () => new Date()
}
},
data() {
return {
timeType: 'date',
timeTypeList: [
{label: '日', value: 'date'},
{label: '月', value: 'month'},
{label: '年', value: 'year'}
]
};
},
computed: {
timeModel: {
get() {
return this.time;
},
set(val) {
this.$emit('update:time', val);
this.$emit('changed', val);
}
}
},
methods: {
handleTimeTypeChanged(val) {
this.timeType = val;
this.$emit('type-changed', val);
}
}
};
</script>
<style lang="scss" scoped>
.day-selector-comp {
display: inline-flex;
gap: 16px;
}
.select-button-list {
display: flex;
.select-button {
display: flex;
align-items: center;
justify-content: center;
width: 64px;
height: 30px;
border: 1px solid #dcdfe6;
border-right: 0;
background: #FFFFFF;
cursor: pointer;
&:first-child {
border-radius: 4px 0 0 4px;
}
&:last-child {
border-radius: 0 4px 4px 0;
border-right: 1px solid #dcdfe6;
}
&.active {
border: 1px solid #457AE6;
background: #457AE6;
color: #FFFFFF;
}
}
}
</style>
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
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
当然,有了这个组件之后,我们可以通过 moment 做一些快捷优雅的操作
比如,写请求参数的时候,我们获取到当前的时间,和选中的类型就可以快速得到目前选中的开始时间和结束时间
let params = {
start_time: moment(this.dateValue).startOf(this.paramDateType).unix(),
end_time: moment(this.dateValue).endOf(this.paramDateType).unix()
};
1
2
3
4
2
3
4
或者按照给出的配置 生成 disabledDate 配置
import moment from 'moment'
const timeTypes = [
{ key: 'date', actionKey: 'day', elType: 'date', label: '日', range: 365 },
{ key: 'week', actionKey: 'week', elType: 'week', label: '周', range: 52 },
{ key: 'month', actionKey: 'month', elType: 'month', label: '月', range: 12 },
{ key: 'quarter', actionKey: 'quarter', elType: 'month', label: '季度', range: 4 },
{ key: 'year', actionKey: 'year', elType: 'year', label: '年', range: 1 }
]
const timeMap = timeTypes.reduce((map, item) => {
map[item.key] = item
return map
}, {})
const getPickerOptions = (currentTime, type) => {
const beforeTime = moment(currentTime).subtract(timeMap[type].range, timeMap[type].actionKey);
const afterTimer = moment(currentTime)
return {
// type,
// beforeTime,
// afterTimer,
disabledDate: (time) => {
return moment(time).isBefore(beforeTime) ||
moment(time).isAfter(afterTimer);
}
}
}
// 没啥意义的测试
const output = (content) => {
const el = document.createElement('div')
el.innerHTML = `<pre>${JSON.stringify(content, null, 2)}</pre>`
document.getElementById("app").appendChild(el)
}
const currentTime = new Date().valueOf()
Object.keys(timeMap).forEach((key) => {
const option = getPickerOptions(currentTime, key);
console.log(option);
output(option);
})
// vue 中可能的用法(未测试)
export default {
watch: {
paramDateType: {
handler(val) {
let beforeTime = moment(this.currentTime).subtract(timeMap[val].range, timeMap[val].key + 's');
this.pickerOption = {
disabledDate: (time) => {
return moment(time).isBefore(beforeTime) ||
moment(time).isAfter(moment(this.currentTime));
}
}
},
immediate: true
}
}
}
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
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
上次更新: 2023/06/01, 12:40:50