CountDown.vue 2.0 KB

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