| 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
 | | <template> |  |     <view class="uni-countdown"> |  |         <text v-if="showDay" :style="[timeStyle]" class="uni-countdown__number">{{ d }}</text> |  |         <text v-if="showDay" :style="[splitorStyle]" class="uni-countdown__splitor">{{dayText}}</text> |  |         <text :style="[timeStyle]" class="uni-countdown__number">{{ h }}</text> |  |         <text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : hourText }}</text> |  |         <text :style="[timeStyle]" class="uni-countdown__number">{{ i }}</text> |  |         <text :style="[splitorStyle]" class="uni-countdown__splitor">{{ showColon ? ':' : minuteText }}</text> |  |         <text :style="[timeStyle]" class="uni-countdown__number">{{ s }}</text> |  |         <text v-if="!showColon" :style="[splitorStyle]" class="uni-countdown__splitor">{{secondText}}</text> |  |     </view> |  | </template> |  | <script> |  |     import { |  |         initVueI18n |  |     } from '@dcloudio/uni-i18n' |  |     import messages from './i18n/index.js' |  |     const { |  |         t |  |     } = initVueI18n(messages) |  |     /** |  |      * Countdown 倒计时 |  |      * @description 倒计时组件 |  |      * @tutorial https://ext.dcloud.net.cn/plugin?id=25 |  |      * @property {String} backgroundColor 背景色 |  |      * @property {String} color 文字颜色 |  |      * @property {Number} day 天数 |  |      * @property {Number} hour 小时 |  |      * @property {Number} minute 分钟 |  |      * @property {Number} second 秒 |  |      * @property {Number} timestamp 时间戳 |  |      * @property {Boolean} showDay = [true|false] 是否显示天数 |  |      * @property {Boolean} show-colon = [true|false] 是否以冒号为分隔符 |  |      * @property {String} splitorColor 分割符号颜色 |  |      * @event {Function} timeup 倒计时时间到触发事件 |  |      * @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown> |  |      */ |  |     export default { |  |         name: 'UniCountdown', |  |         emits: ['timeup'], |  |         props: { |  |             showDay: { |  |                 type: Boolean, |  |                 default: true |  |             }, |  |             showColon: { |  |                 type: Boolean, |  |                 default: true |  |             }, |  |             start: { |  |                 type: Boolean, |  |                 default: true |  |             }, |  |             backgroundColor: { |  |                 type: String, |  |                 default: '' |  |             }, |  |             color: { |  |                 type: String, |  |                 default: '#333' |  |             }, |  |             fontSize: { |  |                 type: Number, |  |                 default: 14 |  |             }, |  |             splitorColor: { |  |                 type: String, |  |                 default: '#333' |  |             }, |  |             day: { |  |                 type: Number, |  |                 default: 0 |  |             }, |  |             hour: { |  |                 type: Number, |  |                 default: 0 |  |             }, |  |             minute: { |  |                 type: Number, |  |                 default: 0 |  |             }, |  |             second: { |  |                 type: Number, |  |                 default: 0 |  |             }, |  |             timestamp: { |  |                 type: Number, |  |                 default: 0 |  |             } |  |         }, |  |         data() { |  |             return { |  |                 timer: null, |  |                 syncFlag: false, |  |                 d: '00', |  |                 h: '00', |  |                 i: '00', |  |                 s: '00', |  |                 leftTime: 0, |  |                 seconds: 0 |  |             } |  |         }, |  |         computed: { |  |             dayText() { |  |                 return t("uni-countdown.day") |  |             }, |  |             hourText(val) { |  |                 return t("uni-countdown.h") |  |             }, |  |             minuteText(val) { |  |                 return t("uni-countdown.m") |  |             }, |  |             secondText(val) { |  |                 return t("uni-countdown.s") |  |             }, |  |             timeStyle() { |  |                 const { |  |                     color, |  |                     backgroundColor, |  |                     fontSize |  |                 } = this |  |                 return { |  |                     color, |  |                     backgroundColor, |  |                     fontSize: `${fontSize}px`, |  |                     width: `${fontSize * 22 / 14}px`, // 按字体大小为 14px 时的比例缩放 |  |                      lineHeight: `${fontSize * 20 / 14}px`, |  |                     borderRadius: `${fontSize * 3 / 14}px`, |  |                 } |  |             }, |  |             splitorStyle() { |  |                 const { splitorColor, fontSize, backgroundColor } = this |  |                 return { |  |                     color: splitorColor, |  |                     fontSize: `${fontSize * 12 / 14}px`, |  |                     margin: backgroundColor ? `${fontSize * 4 / 14}px` : '' |  |                 } |  |             } |  |         }, |  |         watch: { |  |             day(val) { |  |                 this.changeFlag() |  |             }, |  |             hour(val) { |  |                 this.changeFlag() |  |             }, |  |             minute(val) { |  |                 this.changeFlag() |  |             }, |  |             second(val) { |  |                 this.changeFlag() |  |             }, |  |             start: { |  |                 immediate: true, |  |                 handler(newVal, oldVal) { |  |                     if (newVal) { |  |                         this.startData(); |  |                     } else { |  |                         if (!oldVal) return |  |                         clearInterval(this.timer) |  |                     } |  |                 } |  |   |  |             } |  |         }, |  |         created: function(e) { |  |             this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second) |  |             this.countDown() |  |         }, |  |         // #ifndef VUE3 |  |         destroyed() { |  |             clearInterval(this.timer) |  |         }, |  |         // #endif |  |         // #ifdef VUE3 |  |         unmounted() { |  |             clearInterval(this.timer) |  |         }, |  |         // #endif |  |         methods: { |  |             toSeconds(timestamp, day, hours, minutes, seconds) { |  |                 if (timestamp) { |  |                     return timestamp - parseInt(new Date().getTime() / 1000, 10) |  |                 } |  |                 return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds |  |             }, |  |             timeUp() { |  |                 clearInterval(this.timer) |  |                 this.$emit('timeup') |  |             }, |  |             countDown() { |  |                 let seconds = this.seconds |  |                 let [day, hour, minute, second] = [0, 0, 0, 0] |  |                 if (seconds > 0) { |  |                     day = Math.floor(seconds / (60 * 60 * 24)) |  |                     hour = Math.floor(seconds / (60 * 60)) - (day * 24) |  |                     minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60) |  |                     second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60) |  |                 } else { |  |                     this.timeUp() |  |                 } |  |                 if (day < 10) { |  |                     day = '0' + day |  |                 } |  |                 if (hour < 10) { |  |                     hour = '0' + hour |  |                 } |  |                 if (minute < 10) { |  |                     minute = '0' + minute |  |                 } |  |                 if (second < 10) { |  |                     second = '0' + second |  |                 } |  |                 this.d = day |  |                 this.h = hour |  |                 this.i = minute |  |                 this.s = second |  |             }, |  |             startData() { |  |                 this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second) |  |                 if (this.seconds <= 0) { |  |                     this.seconds = this.toSeconds(0, 0, 0, 0, 0) |  |                     this.countDown() |  |                     return |  |                 } |  |                 clearInterval(this.timer) |  |                 this.countDown() |  |                 this.timer = setInterval(() => { |  |                     this.seconds-- |  |                     if (this.seconds < 0) { |  |                         this.timeUp() |  |                         return |  |                     } |  |                     this.countDown() |  |                 }, 1000) |  |             }, |  |             update(){ |  |                 this.startData(); |  |             }, |  |             changeFlag() { |  |                 if (!this.syncFlag) { |  |                     this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second) |  |                     this.startData(); |  |                     this.syncFlag = true; |  |                 } |  |             } |  |         } |  |     } |  | </script> |  | <style lang="scss" scoped> |  |     $font-size: 14px; |  |   |  |     .uni-countdown { |  |         display: flex; |  |         flex-direction: row; |  |         justify-content: flex-start; |  |         align-items: center; |  |   |  |         &__splitor { |  |             margin: 0 2px; |  |             font-size: $font-size; |  |             color: #333; |  |         } |  |   |  |         &__number { |  |             border-radius: 3px; |  |             text-align: center; |  |             font-size: $font-size; |  |         } |  |     } |  | </style> | 
 |