小程序实现倒计时组件

840 阅读2分钟

先来看倒计时组件实现的功能:

  1. 实现倒计时可以根据需求显示天、时、分、秒,具体时间单位只需修改组件就可以控制是否隐藏
  2. 倒计时结束后自动隐藏

效果如下图

动画2.gif

Screenshot_37.png

直接放源码,这边代码就不进行讲解了,可以根据需求修改代码

js代码
var interval = 1000;
Component({
    /**
     * 组件的属性列表
     */
    properties: {
        // 倒计时时间
        target: {
            type: String,
        },
        // 显示样式类型
        type:{
            type:String,
            value:"list"
        }
    },
    pageLifetimes: {
        hide() {
            // 页面被隐藏
            clearTimeout(this.timer)
        },
        show() {
            if(this.properties.type === 'list') {
                const lastTime = this.initTime(this.properties).lastTime;
                if(lastTime > interval){
                    this.defaultFormat(lastTime);
                    this.setData({
                        isCount: true,
                        lastTime
                    })
    
                    this.tick();
                }
            }
        },

    },
    lifetimes: {
        created() {

        },
        attached() {
         
        },
        ready() {
            const lastTime = this.initTime(this.properties).lastTime;
            if(lastTime > interval){
                this.defaultFormat(lastTime);
                this.setData({
                    isCount: true,
                    lastTime
                })
                this.tick();
            }
        }, 
        moved() {

        }, 
        detached() {
            //组件销毁时清除定时器 防止爆栈
            clearTimeout(this.timer)
        },
    },

    /**
     * 组件的初始数据
     */
    data: {
        d: 0, //天
        h: 0, //时
        m: 0, //分
        s: 0, //秒
        lastTime: '', //倒计时的时间错
        isCount: false, // 倒计时是否完成
    },

    /**
     * 组件的方法列表
     */
    methods: {
        //默认处理时间格式
        defaultFormat(time) {
            const days = 60 * 60 * 1000 *24;
            const hours = 60 * 60 * 1000;
            const minutes = 60 * 1000;
            const d = Math.floor(time / days);
            const h = Math.floor((time % days)/hours);
            // 需求按分显示需+1,按秒显示需要去掉
            const m = Math.floor((time % hours) / minutes + 1);
            const s = Math.floor((time % minutes) / 1000);
            this.setData({
                d: this.fixedZero(d),
                h: this.fixedZero(h),
                m: this.fixedZero(m),
                s: this.fixedZero(s),
            });
            // console.log(this.data.type, d, "天", h, "小时", m, "分", s, "秒")
        },

        //定时事件
        tick() {
            const that = this;
            let { lastTime } = this.data;
            that.timer = setTimeout(() => {
                clearTimeout(that.timer);
                if (lastTime < interval) {
                    that.setData(
                        {   
                            lastTime: 0,
                            isCount: false,
                        },
                        () => {
                            that.defaultFormat(0);
                            if (that.onEnd) {
                                that.onEnd();
                            }
                        }
                    );
                } else {
                    lastTime -= 1000;
                    that.setData(
                        {
                            lastTime,
                        },
                        () => {
                            that.defaultFormat(lastTime);
                            that.tick();
                        }
                    );
                }
            }, interval);
        },

        //初始化时间
        initTime(properties) {
            let lastTime = 0;
            lastTime = Number(properties.target) - new Date().getTime();
            return {
                lastTime: lastTime < 0 ? 0 : lastTime,
            };
        },
        //时间结束回调事件
        onEnd() {
            this.triggerEvent('onEnd', { isCount: this.data.isCount}, {});
        },
        // 格式化时间加0
        fixedZero(val) {
            return val * 1 < 10 ? '0' + val : val;
        },
    },
});


wxml代码
<view wx:if="{{isCount && type === 'list'}}" class="list">
    <view class="title">开课倒计时:</view>
    <text class="count-down">{{d}}天{{h}}小时{{m}}分</text>
</view>
<view wx:if="{{isCount && type === 'list'}}" class="course-warn">
        <image class="img-problem" src="https://s.gaodunwangxiao.com/static-shanganya/private-education/lesson/icon-question.png" />
        <view class="text">您可提前15分钟进入直播间做准备</view>
</view>
<view wx:if="{{isCount && type === 'detail'}}" class="timeText">开课倒计时:</view>
<view wx:if="{{isCount && type === 'detail'}}" class="detail">
    <view class="time-wrapper">{{d}}</view>
    <text class="time-text">天</text>
    <view class="time-wrapper">{{h}}</view>
    <text class="time-text">小时</text>
    <view class="time-wrapper">{{m}}</view>
    <text class="time-text">分钟</text>
</view>
less代码
.list {
    display: flex;
    margin-bottom: 24rpx;
    .title {
        font-size: 28rpx;
        line-height: 40rpx;
        letter-spacing: 1rpx;
        font-weight: 500;
        color: #343434;
    }
    .count-down {
        color: #999999;
        font-size: 28rpx;
        line-height: 40rpx;
        display: flex;
        align-items: center;
        padding-left: 15rpx;
    }

}
.course-warn {
    display: flex;
    align-items: center;
    margin-bottom: 24rpx;
    .img-problem {
        width: 26rpx;
        height: 26rpx;
    }
    .text {
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fc8626;
        font-size: 24rpx;
        line-height: 26rpx;
        letter-spacing: 1rpx;
        margin-left: 8rpx;
    }
}
.timeText {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 32rpx;
    line-height: 44rpx;
    color: #333333;
    font-weight: 600;
    letter-spacing: 1rpx;
    margin-top: -39rpx;
}
.detail {
        padding-top: 26rpx;
        display: flex;
        letter-spacing: 8rpx;
        padding-bottom: 26rpx;
        .time-wrapper {
            font-size: 40rpx;
            line-height: 56rpx;
            color: #fc8626;
            margin-top: -8rpx;
        }
        .time-text {
            font-size: 32rpx;
            line-height: 44rpx;
            color: #333333;
            font-weight: 600;
        }
    
}