vue自定义倒计时组件(测试毫秒级)

583 阅读1分钟

setInterval尽量不低于50毫秒

<template>
  <div class="count-time">
    <span class="key key0">{{ minutes }}</span>分
    <span class="key">{{ seconds }}</span>秒
    <span class="key">{{ hseconds }}</span>毫秒
  </div>
</template>
<script>

export default {
  name: 'ActivityCountTime',
  data () {
    return {
      timer: null,
      countTimeCopy: 0,
      lastTime: null
    }
  },
  computed: {
    days() {
      let day = Math.floor(this.countTimeCopy / (24 * 3600 * 1000))
      return day > 9 ? day : '0' + day
    },
    hours() {
      let restTime = this.countTimeCopy - this.days * 24 * 3600 * 1000
      let hours = Math.floor(restTime / (60 * 60 * 1000))
      return hours > 9 ? hours : '0' + hours
    },
    minutes() {
      let restTime = this.countTimeCopy - this.days * 24 * 3600 * 1000 - this.hours * 60 * 60 * 1000
      let minutes = Math.floor(restTime / (60 * 1000))
      return minutes > 9 ? minutes : '0' + minutes
    },
    seconds() {
      let restTime = this.countTimeCopy - this.days * 24 * 3600 * 1000 - this.hours * 60 * 60 * 1000 - this.minutes * 60 * 1000
      let seconds = Math.floor(restTime / 1000)
      return seconds > 9 ? seconds : '0' + seconds
    },
    hseconds() {
      let restTime = this.countTimeCopy - this.days * 24 * 3600 * 1000 - this.hours * 60 * 60 * 1000 - this.minutes * 60 * 1000 - this.seconds * 1000
      let hseconds = Math.floor(restTime)
      return hseconds > 9 ? hseconds : '0' + hseconds
      //return hseconds > 100 ? hseconds : hseconds < 100 && hseconds > 10 ? '0' +  hseconds : '00' + hseconds
    }
  },
  watch: {
    countTimeReduce (val) {
      if (val > 0) {
        this.countTimeCopy = val
        this.countTimes()
      }
    }
  },
  props: {
    countTimeReduce: {
      type: Number,
      default: 0
    },
    timeEndCb: {
      type: Function,
      default: () => {}
    }
  },
  methods: {
    countTimes () {
      let _this = this
      this.timer && clearInterval(this.timer)
      this.timer = setInterval(() => {
        if (_this.countTimeCopy > 0) {
          _this.countTimeCopy = _this.countTimeCopy - 50 > 0 ? (_this.countTimeCopy - 50) : 0
        } else {
          clearInterval(_this.timer)
          _this.timeEndCb()
        }
      }, 50)
    },
    // 解决熄屏问题
    computedTime () {
      if(document.visibilityState === 'hidden') {
        if (this.timer) {
          clearInterval(this.timer)
          this.lastTime = Date.now()
        }
      } else {
        let time = Date.now() - this.lastTime
        this.countTimeCopy = this.countTimeCopy - time > 0 ? this.countTimeCopy - time : 0

        this.timer = setInterval(() => {
          if (this.countTimeCopy > 0) {
            this.countTimeCopy = this.countTimeCopy - 50 > 0 ? (this.countTimeCopy - 50) : 0
          } else {
            clearInterval(this.timer)
            this.timeEndCb()
          }
        }, 50)
      }
    }
  },
  mounted() {
    document.addEventListener('visibilitychange', this.computedTime)
  },
  beforeDestroy () {
    this.timer && clearInterval(this.timer)
    document.removeEventListener('visibilitychange', this.computedTime)
  }
}
</script>
<style lang="less" scoped>
  .key {
    color: #DC1860;
    margin: 0 6px;
    &.key0 {
      margin-left: 0;
    }
    &.key1 {
      margin: 0 2px;
    }
  }
</style>