倒计时组件

倒计时组件

<template>

  <div class="container">

    <!-- 一个元素显示倒计时 -->
    <div v-show="isEndStatus" v-if="!manyElement" :style="{ color }">{{ countDownItem }}</div>

    <!-- 多元素倒计时 -->
    <div v-show="isEndStatus" :style="{ color }" v-else>
      <slot name="customMany" :slot-scope="splitElement">
        <span v-for="(item, index) in splitElement" :key="index">
          {{ index !== splitElement.length - 1 ? item + separator : item }}
        </span>
      </slot>
    </div>
  </div>

</template>
<script>
export default {
  name: 'count-down',
  props: {
    // 结束的时间毫秒数
    actEndTime: {
      type: Number,
      default: Date.now() + 10000
    },
    // 显示倒计时格式
    countDownList: {
      type: String,
      default: 'dd-hh-mm-xx'
    },
    // 字体颜色
    color: {
      type: String,
      default: '#000000'
    },
    // 分隔符
    separator: {
      type: String,
      default: ''
    },
    // 是否开启多元素显示效果
    manyElement: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      countDownItem: '',
      newTime: null,
      // 倒计时是否执行完毕
      isEndStatus: true
    }
  },
  computed: {
    // 多元素显示处理
    splitElement () {
      if (this.manyElement) {
        return this.countDownItem.split(this.separator || ' ')
      }
      return this.countDownItem.split(this.separator)
    }
  },
  methods: {
    timeFormat (param) {
      return param < 10 ? '0' + param : param
    },
    countDown () {
      const interval = setInterval(() => {
        const newTime = new Date().getTime()
        const endTime = new Date(this.actEndTime + 2000).getTime()
        let obj = null
        if (endTime - newTime > 0) {
          const time = (endTime - newTime) / 1000
          const day = parseInt(time / (60 * 60 * 24))
          const hou = parseInt((time % (60 * 60 * 24)) / 3600)
          const min = parseInt(((time % (60 * 60 * 24)) % 3600) / 60)
          const sec = parseInt(((time % (60 * 60 * 24)) % 3600) % 60)
          obj = {
            dd: this.timeFormat(day),
            hh: this.timeFormat(hou),
            mm: this.timeFormat(min),
            xx: this.timeFormat(sec)
          }
          if (this.newTime) {
            this.$emit('start-click', this.newTime)
          }
        } else {
          // 倒计时结束
          obj = {
            dd: '00',
            hh: '00',
            mm: '00',
            xx: '00'
          }
          this.isEndStatus = false
          clearInterval(interval)
          this.$emit('end-click', this.countDownItem)
        }
        const timeList = this.countDownList.split('-')
        const dateList = ['日', '时', '分', '秒']
        this.newTime = ''
        // 循环判断如果用户传过来的日期,包含对象中的属性,那么就使用该属性的值
        Object.keys(obj).forEach((key, index) => {
          if (timeList.includes(key)) {
            // 如果是最后一组,就不加分隔符
            const separLen = index !== dateList.length - 1 ? this.separator : ''
            // 判断数据占位元素问题
            if (this.manyElement) {
              this.newTime += obj[key] += dateList[index] + ' ' + separLen
            } else {
              this.newTime += obj[key] += dateList[index] += separLen
            }
          }
        })
        this.countDownItem = this.newTime
      }, 1000)
    }
  },
  mounted () {
    this.countDown()
  }
}
</script>
// 参数详解

/*

    1.actEndTime(Number):倒计时结束的时间,毫秒数

    2.countDownList(String):倒计时显示的时间要求(dd(日)-hh(时)-mm(分)-xx(秒))

    3.color(String):字体颜色

    4.separator(String):分隔符

    5.manyElement(Boolean):是否开启多元素显示效果

*/
原文地址:https://www.cnblogs.com/zxuedong/p/13058952.html