倒计时组件

237 阅读1分钟

实现效果

image.png

组件要求

  1. 满足基本文字型倒计时
  2. 支持自定义样式倒计时
    • 留出自定义类
    • 留出自定义插槽

倒计时组件代码

    <template>
        <div class="count-down-component" :class="[activeClass]" :style="{
            background:backgroundColor,
            color:textColor,
            borderRadius,
            fontSize
        }">
           <slot name="default" :countData="{
            hours,minutes,seconds
           }">
                <span v-show="showHour">{{ hours }} : </span>
                <span>{{ minutes }} : </span>
                <span>{{ seconds }}</span> 
           </slot>
        </div>
    </template>
    <style scoped>
        .count-down-component{
            width: fit-content;
            padding: 3px 6px;
            box-sizing: border-box;
        } 
    </style>
    <script>
        export default{
        name:'BiteCountDown',
        props:{
            fontSize:{
                type:String,
                default:'12px'
            },
            activeClass:{
                type:String,
                default:'' // 自定义类名
            },
            backgroundColor:{
                type:String,
                default:'' // 默认背景透明色
            },
            textColor:{
                type:String,
                default:'' // 默认字体颜色黑色
            },
            borderRadius:{
                type:String,
                default:'' // 默认圆角
            },
            // 倒计时总时长
            burningTime:{
                type:Number,
                default:10,// 单位s
            },
            // 是否展示小时
            showHour:{
                type:Boolean,
                default:false
            },
        },
        data(){
            return {
                hours:' ',
                minutes:' ',
                seconds:' ',
                timer:null,
                downTime:10
            }
        },
        watch:{
            burningTime:function(newVal){
                this.downTime = newVal
                this.cuntDownFun()
            }
        },
        methods:{
            // 处理时间 转化成时分秒
            dealBurningTime(){
                if(this.showHour){
                    this.hours = this.formatNumber(Math.floor(this.downTime/3600))
                    this.minutes = this.formatNumber(Math.floor((this.downTime - this.hours*3600)/60))
                    this.seconds = this.formatNumber(Math.floor(this.downTime - this.hours*3600 - this.minutes*60))
                } else {
                    this.minutes = this.formatNumber(Math.floor(this.downTime/60))
                    this.seconds = this.formatNumber(Math.floor(this.downTime - this.minutes*60))
                }
            },
            // 格式化数字
            formatNumber(val){
                let result = ''
                if(+val<10){
                    result = '0'+val
                }else{
                    result = val || '00'
                }
                return result
            },
            // 倒计时
            cuntDownFun(){
                this.timer && clearInterval(this.timer)
                this.timer = setInterval(()=>{
                    if(this.downTime<1){
                        clearInterval(this.timer)
                        return
                    }
                    this.downTime-=1
                    this.dealBurningTime()
                },1000)
            }
        }

    }
    </script>

组件使用方法

<template>
  <div class="cus-box">
    <!-- 自定义属性 -->
    <BiteCountDown :burningTime="burningTime" :showHour="true"></BiteCountDown>
    <BiteCountDown :burningTime="burningTime" ></BiteCountDown>
    <BiteCountDown :burningTime="burningTime" backgroundColor="red" textColor="#fff" borderRadius="20px"></BiteCountDown>
    <!-- 自定义类名 -->
    <BiteCountDown :burningTime="burningTime" activeClass="my-count-down"></BiteCountDown>
    <!-- 自定义插槽 -->
    <BiteCountDown :burningTime="burningTime" :showHour="true">
      <template v-slot="{countData}">
        <div class="slot-count-down">
          剩余 <span v-show="+countData.hours"> <i>{{ countData.hours }}</i> 小时 </span><span><i>{{ countData.minutes }}</i></span> <span><i>{{ countData.seconds }}</i></span>
        </div>
        <!-- <span> ssssssssss {{ JSON.stringify(countData) }}</span> -->
      </template>
    </BiteCountDown>
  </div>
</template>

<script>
import BiteCountDown from '../../packages/countdown';
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  components:{
    BiteCountDown
  },
  data(){
    return{
      burningTime:null
    }
  },
  mounted(){
    setTimeout(() => {
      this.burningTime = 3800
    }, 10);
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.my-count-down{
  background: #42b983;
  color: #fff;
  border-radius: 3px;
  margin-top: 10px;
}
.slot-count-down span{
  display: inline-block;
  font-size: 13px;
  margin-top: 10px;
  margin-right: 3px;
}
.slot-count-down span i{
  display: inline-block;
  padding: 5px;
  background: #5b5b5b;
  font-style: normal;
  font-weight: bold;
  font-size: 14px;
  color: #fff;
}
</style>