1
1
<template >
2
2
<div class =" datePicker" >
3
3
<div class =" datePicker_header" >
4
- <button class =" datePicker_close" >
4
+ <button
5
+ class =" datePicker_close"
6
+ @click =" closeHandler"
7
+ >
5
8
<i class =" fas fa-times" />
6
9
</button >
7
10
<div class =" datePicker_title" >
8
11
<span class =" datePicker_icon" ><i class =" far fa-calendar text-white" /></span >
9
12
<span class =" datePicker_title_content" >選擇日期</span >
10
13
</div >
14
+ <!-- 當月標題 -->
11
15
<div class =" datePicker_month_title" >
12
- 2020 / 06
16
+ {{ currentMonthLabel.year }} / {{ currentMonthLabel.month }}
13
17
</div >
18
+ <!-- 週標 -->
14
19
<div class =" datePicker_weekday" >
15
20
<span
16
- v-for =" i in 7"
17
- :key =" 70 + i "
21
+ v-for =" d in 7"
22
+ :key =" 84 + d "
18
23
class =" datePicker_weekday_label"
19
- >{{ i }}</span >
24
+ >{{ getWeekday(d-1) }}</span >
20
25
</div >
21
26
</div >
22
27
<div class =" datePicker_body" >
28
+ <!-- 當月 -->
23
29
<div class =" datePicker_month current" >
24
30
<div
25
- v-for =" i in 35 "
31
+ v-for =" (day, i) in daysOfMonthWithClass "
26
32
:key =" i"
27
- class =" datePicker_date today"
28
- >
29
- {{ i }}
30
- </div >
33
+ class =" datePicker_date"
34
+ :class =" {'today': day.isToday, 'disabled': day.disabled, 'selected': day.selected}"
35
+ @click =" selectHandler(day)"
36
+ v-text =" day.disabled? '': day.date"
37
+ />
31
38
</div >
39
+ <!-- 次月標題 -->
32
40
<div class =" datePicker_month_title pt-3" >
33
- 2020 / 07
41
+ {{ nextMonthLabel.year }} / {{ nextMonthLabel.month }}
34
42
</div >
35
-
43
+ <!-- 次月 -->
36
44
<div class =" datePicker_month next" >
37
45
<div
38
- v-for =" i in 35 "
39
- :key =" 35 + i"
46
+ v-for =" (day, i) in daysOfNextMonthWithClass "
47
+ :key =" 42 + i"
40
48
class =" datePicker_date"
41
- >
42
- {{ i }}
43
- </div >
49
+ :class =" {'today': day.isToday, 'disabled': day.disabled, 'selected': day.selected}"
50
+ @click =" selectHandler(day)"
51
+ v-text =" day.disabled? '': day.date"
52
+ />
44
53
</div >
45
54
</div >
46
55
<div class =" datePicker_select" >
47
- <button class =" btn btn-primary" >
56
+ <button
57
+ class =" btn btn-primary"
58
+ @click =" confirmSelect"
59
+ >
48
60
選擇
49
61
</button >
50
62
</div >
55
67
export default {
56
68
name: ' DatePicker' ,
57
69
props: {
70
+ current: { type: Date , required: true },
71
+ calendar: { type: Object , required: true },
72
+ daysOfMonth: { type: Array , required: true },
73
+ daysOfNextMonth: { type: Array , required: true }
74
+ },
75
+ data () {
76
+ return {
77
+ select: {
78
+ year: 0 ,
79
+ month: 0 ,
80
+ date: 0 ,
81
+ weekDay: 0
82
+ }
83
+ }
84
+ },
85
+ computed: {
86
+ today () {
87
+ const { current } = this
88
+ return {
89
+ year: current .getFullYear (),
90
+ month: current .getMonth (),
91
+ date: current .getDate (),
92
+ weekDay: current .getDay ()
93
+ }
94
+ },
95
+ getWeekday () {
96
+ const { daysOfMonth } = this
97
+ const mapDay = {
98
+ 1 : ' M' ,
99
+ 2 : ' T' ,
100
+ 3 : ' W' ,
101
+ 4 : ' T' ,
102
+ 5 : ' F' ,
103
+ 6 : ' S' ,
104
+ 0 : ' S'
105
+ }
106
+ return (d ) => mapDay[daysOfMonth[d].weekDay ]
107
+ },
108
+ currentMonth () {
109
+ const { year , month } = this .calendar
110
+ const cDate = new Date (year, month, 1 )
111
+ return { year: cDate .getFullYear (), month: cDate .getMonth () }
112
+ },
113
+ currentMonthLabel () {
114
+ const { year , month } = this .currentMonth
115
+ return { year, month: (month + 1 ).toString ().padStart (2 , ' 0' ) }
116
+ },
117
+ nextMonth () {
118
+ const { year , month } = this .currentMonth
119
+ const mDate = new Date (year, month + 1 , 1 )
120
+ return { year: mDate .getFullYear (), month: mDate .getMonth () }
121
+ },
122
+ nextMonthLabel () {
123
+ const { year , month } = this .nextMonth
124
+ return { year, month: (month + 1 ).toString ().padStart (2 , ' 0' ) }
125
+ },
126
+ daysOfMonthWithClass () {
127
+ const { daysOfMonth , select } = this
128
+ const { year , month , date } = this .today
129
+ const currentMonth = this .currentMonth .month
130
+ return daysOfMonth .map (day => {
131
+ const disabled = day .month !== currentMonth
58
132
133
+ return {
134
+ ... day,
135
+ disabled,
136
+ selected: ! disabled && select .year === day .year && select .month === day .month && select .date === day .date ,
137
+ isToday: ! disabled && year === day .year && month === day .month && date === day .date
138
+ }
139
+ })
140
+ },
141
+ daysOfNextMonthWithClass () {
142
+ const { daysOfNextMonth , select } = this
143
+ const currentMonth = this .nextMonth .month
144
+ return daysOfNextMonth .map (day => {
145
+ const disabled = day .month !== currentMonth
146
+ return {
147
+ ... day,
148
+ disabled,
149
+ selected: ! disabled && select .year === day .year && select .month === day .month && select .date === day .date
150
+ }
151
+ })
152
+ }
59
153
},
60
- computed: {}
154
+ methods: {
155
+ closeHandler () {
156
+ this .$emit (' switchPicker' )
157
+ },
158
+ selectHandler (day ) {
159
+ if (day .disabled ) return
160
+ const { year , month , date , weekDay } = day
161
+ this .select .year = year
162
+ this .select .month = month
163
+ this .select .date = date
164
+ this .select .weekDay = weekDay
165
+ },
166
+ confirmSelect () {
167
+ this .$emit (' input' , this .select )
168
+ this .$emit (' switchPicker' )
169
+ }
170
+ }
61
171
}
62
172
</script >
63
173
@@ -131,15 +241,16 @@ export default {
131
241
}
132
242
& _date {
133
243
width : calc (90vw / 7 );
134
- padding : 1 rem ;
244
+ padding : 0.5 rem 0.5 rem ;
135
245
cursor : pointer ;
136
246
position : relative ;
247
+ text-align : center ;
137
248
138
249
& :hover {
139
250
& ::before {
140
251
content : " " ;
141
252
left : calc (50% - 1rem );
142
- top : calc ( 50 % - 1 rem ) ;
253
+ top : 0.25 rem ;
143
254
width : 2rem ;
144
255
height : 2rem ;
145
256
border-radius : 50% ;
@@ -154,7 +265,7 @@ export default {
154
265
& ::before {
155
266
content : " " ;
156
267
left : calc (50% - 1rem );
157
- top : calc ( 50 % - 1 rem ) ;
268
+ top : 0.25 rem ;
158
269
width : 2rem ;
159
270
height : 2rem ;
160
271
border-radius : 50% ;
@@ -164,6 +275,14 @@ export default {
164
275
z-index : -1 ;
165
276
}
166
277
}
278
+ & .disabled {
279
+ color : #f2f2f2 ;
280
+ background-color : #f2f2f2 ;
281
+ cursor : default ;
282
+ & :hover ::before {
283
+ display : none ;
284
+ }
285
+ }
167
286
& .today ::after {
168
287
width : 8px ;
169
288
height : 8px ;
@@ -176,6 +295,13 @@ export default {
176
295
}
177
296
}
178
297
& _select {
298
+ position : absolute ;
299
+ left : 0 ;
300
+ bottom : 0 ;
301
+ display : block ;
302
+ width : 100% ;
303
+ height : 4.2rem ;
304
+ padding-top : 1rem ;
179
305
> button {
180
306
width : 9rem ;
181
307
border-radius : 10px ;
0 commit comments