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
| <template>
| <span>
| {{ lastTime | format }}
| </span>
| </template>
|
| <script>
|
| function fixedZero (val) {
| return val * 1 < 10 ? `0${val}` : val
| }
|
| export default {
| name: 'CountDown',
| props: {
| format: {
| type: Function,
| default: undefined
| },
| target: {
| type: [Date, Number],
| required: true
| },
| onEnd: {
| type: Function,
| default: () => ({})
| }
| },
| data () {
| return {
| dateTime: '0',
| originTargetTime: 0,
| lastTime: 0,
| timer: 0,
| interval: 1000
| }
| },
| filters: {
| format (time) {
| const hours = 60 * 60 * 1000
| const minutes = 60 * 1000
|
| const h = Math.floor(time / hours)
| const m = Math.floor((time - h * hours) / minutes)
| const s = Math.floor((time - h * hours - m * minutes) / 1000)
| return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
| }
| },
| created () {
| this.initTime()
| this.tick()
| },
| methods: {
| initTime () {
| let lastTime = 0
| let targetTime = 0
| this.originTargetTime = this.target
| try {
| if (Object.prototype.toString.call(this.target) === '[object Date]') {
| targetTime = this.target
| } else {
| targetTime = new Date(this.target).getTime()
| }
| } catch (e) {
| throw new Error('invalid target prop')
| }
|
| lastTime = targetTime - new Date().getTime()
|
| this.lastTime = lastTime < 0 ? 0 : lastTime
| },
| tick () {
| const { onEnd } = this
|
| this.timer = setTimeout(() => {
| if (this.lastTime < this.interval) {
| clearTimeout(this.timer)
| this.lastTime = 0
| if (typeof onEnd === 'function') {
| onEnd()
| }
| } else {
| this.lastTime -= this.interval
| this.tick()
| }
| }, this.interval)
| }
| },
| beforeUpdate () {
| if (this.originTargetTime !== this.target) {
| this.initTime()
| }
| },
| beforeDestroy () {
| clearTimeout(this.timer)
| }
| }
| </script>
|
| <style scoped>
|
| </style>
|
|