inleft
2022-02-09 9bcb19959eeb9da9bde2561e7278f6d0a55eb151
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>