Skip to content

Commit 55123f7

Browse files
author
BYSu
committed
串接日期資料 & 選擇控制
1 parent c55b8fc commit 55123f7

File tree

4 files changed

+265
-25
lines changed

4 files changed

+265
-25
lines changed

src/assets/style/_animate.scss

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
opacity: 1;
2525
}
2626

27-
.scale-out-enter-active{
27+
.scale-out-enter-active {
2828
transition: 1s;
2929
}
3030
.scale-out-leave-active {
@@ -43,3 +43,18 @@
4343
transform: scaleX(1);
4444
opacity: 1;
4545
}
46+
47+
.fade-enter,
48+
.fade-leave-to {
49+
opacity: 0;
50+
}
51+
52+
.fade-enter-to,
53+
.fade-leave {
54+
opacity: 1;
55+
}
56+
57+
.fade-enter-active,
58+
.fade-leave-active {
59+
transition: 0.5s;
60+
}

src/components/Week/DatePicker.vue

+148-22
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,62 @@
11
<template>
22
<div class="datePicker">
33
<div class="datePicker_header">
4-
<button class="datePicker_close">
4+
<button
5+
class="datePicker_close"
6+
@click="closeHandler"
7+
>
58
<i class="fas fa-times" />
69
</button>
710
<div class="datePicker_title">
811
<span class="datePicker_icon"><i class="far fa-calendar text-white" /></span>
912
<span class="datePicker_title_content">選擇日期</span>
1013
</div>
14+
<!-- 當月標題 -->
1115
<div class="datePicker_month_title">
12-
2020 / 06
16+
{{ currentMonthLabel.year }} / {{ currentMonthLabel.month }}
1317
</div>
18+
<!-- 週標 -->
1419
<div class="datePicker_weekday">
1520
<span
16-
v-for="i in 7"
17-
:key="70 + i"
21+
v-for="d in 7"
22+
:key="84 + d"
1823
class="datePicker_weekday_label"
19-
>{{ i }}</span>
24+
>{{ getWeekday(d-1) }}</span>
2025
</div>
2126
</div>
2227
<div class="datePicker_body">
28+
<!-- 當月 -->
2329
<div class="datePicker_month current">
2430
<div
25-
v-for="i in 35"
31+
v-for="(day, i) in daysOfMonthWithClass"
2632
: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+
/>
3138
</div>
39+
<!-- 次月標題 -->
3240
<div class="datePicker_month_title pt-3">
33-
2020 / 07
41+
{{ nextMonthLabel.year }} / {{ nextMonthLabel.month }}
3442
</div>
35-
43+
<!-- 次月 -->
3644
<div class="datePicker_month next">
3745
<div
38-
v-for="i in 35"
39-
:key=" 35 + i"
46+
v-for="(day, i) in daysOfNextMonthWithClass"
47+
:key="42 + i"
4048
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+
/>
4453
</div>
4554
</div>
4655
<div class="datePicker_select">
47-
<button class="btn btn-primary">
56+
<button
57+
class="btn btn-primary"
58+
@click="confirmSelect"
59+
>
4860
選擇
4961
</button>
5062
</div>
@@ -55,9 +67,107 @@
5567
export default {
5668
name: 'DatePicker',
5769
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
58132
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+
}
59153
},
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+
}
61171
}
62172
</script>
63173

@@ -131,15 +241,16 @@ export default {
131241
}
132242
&_date {
133243
width: calc(90vw / 7);
134-
padding: 1rem;
244+
padding: 0.5rem 0.5rem;
135245
cursor: pointer;
136246
position: relative;
247+
text-align: center;
137248
138249
&:hover {
139250
&::before {
140251
content: "";
141252
left: calc(50% - 1rem);
142-
top: calc(50% - 1rem);
253+
top: 0.25rem;
143254
width: 2rem;
144255
height: 2rem;
145256
border-radius: 50%;
@@ -154,7 +265,7 @@ export default {
154265
&::before {
155266
content: "";
156267
left: calc(50% - 1rem);
157-
top: calc(50% - 1rem);
268+
top: 0.25rem;
158269
width: 2rem;
159270
height: 2rem;
160271
border-radius: 50%;
@@ -164,6 +275,14 @@ export default {
164275
z-index: -1;
165276
}
166277
}
278+
&.disabled {
279+
color: #f2f2f2;
280+
background-color: #f2f2f2;
281+
cursor: default;
282+
&:hover::before {
283+
display: none;
284+
}
285+
}
167286
&.today::after {
168287
width: 8px;
169288
height: 8px;
@@ -176,6 +295,13 @@ export default {
176295
}
177296
}
178297
&_select {
298+
position: absolute;
299+
left: 0;
300+
bottom: 0;
301+
display: block;
302+
width: 100%;
303+
height: 4.2rem;
304+
padding-top: 1rem;
179305
> button {
180306
width: 9rem;
181307
border-radius: 10px;

src/components/Week/WeekHeader.vue

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<template>
22
<div class="weekHeader">
3-
<div class="weekHeader_col">
3+
<div
4+
class="weekHeader_col"
5+
@click="openHandler"
6+
>
47
<span class="weekHeader_icon text-primary"><i class="far fa-calendar" /></span>
58
</div>
69
<div
@@ -74,6 +77,9 @@ export default {
7477
setActiveDay (weekDay) {
7578
this.activeDay = weekDay
7679
this.$emit('selectDate', this.daysOfWeek[weekDay])
80+
},
81+
openHandler () {
82+
this.$emit('switchPicker', true)
7783
}
7884
}
7985
}

0 commit comments

Comments
 (0)