inleft
2022-02-09 9bcb19959eeb9da9bde2561e7278f6d0a55eb151
commit | author | age
9bcb19 1 <template>
I 2   <span>
3     {{ lastTime | format }}
4   </span>
5 </template>
6
7 <script>
8
9 function fixedZero (val) {
10   return val * 1 < 10 ? `0${val}` : val
11 }
12
13 export default {
14   name: 'CountDown',
15   props: {
16     format: {
17       type: Function,
18       default: undefined
19     },
20     target: {
21       type: [Date, Number],
22       required: true
23     },
24     onEnd: {
25       type: Function,
26       default: () => ({})
27     }
28   },
29   data () {
30     return {
31       dateTime: '0',
32       originTargetTime: 0,
33       lastTime: 0,
34       timer: 0,
35       interval: 1000
36     }
37   },
38   filters: {
39     format (time) {
40       const hours = 60 * 60 * 1000
41       const minutes = 60 * 1000
42
43       const h = Math.floor(time / hours)
44       const m = Math.floor((time - h * hours) / minutes)
45       const s = Math.floor((time - h * hours - m * minutes) / 1000)
46       return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
47     }
48   },
49   created () {
50     this.initTime()
51     this.tick()
52   },
53   methods: {
54     initTime () {
55       let lastTime = 0
56       let targetTime = 0
57       this.originTargetTime = this.target
58       try {
59         if (Object.prototype.toString.call(this.target) === '[object Date]') {
60           targetTime = this.target
61         } else {
62           targetTime = new Date(this.target).getTime()
63         }
64       } catch (e) {
65         throw new Error('invalid target prop')
66       }
67
68       lastTime = targetTime - new Date().getTime()
69
70       this.lastTime = lastTime < 0 ? 0 : lastTime
71     },
72     tick () {
73       const { onEnd } = this
74
75       this.timer = setTimeout(() => {
76         if (this.lastTime < this.interval) {
77           clearTimeout(this.timer)
78           this.lastTime = 0
79           if (typeof onEnd === 'function') {
80             onEnd()
81           }
82         } else {
83           this.lastTime -= this.interval
84           this.tick()
85         }
86       }, this.interval)
87     }
88   },
89   beforeUpdate () {
90     if (this.originTargetTime !== this.target) {
91       this.initTime()
92     }
93   },
94   beforeDestroy () {
95     clearTimeout(this.timer)
96   }
97 }
98 </script>
99
100 <style scoped>
101
102 </style>