zoukankan      html  css  js  c++  java
  • vue 设计一个倒计时秒杀的组件

    简介:

    倒计时秒杀组件在电商网站中层出不穷  不过思路万变不离其踪,我自己根据其他资料设计了一个vue版的

    核心思路:1、时间不能是本地客户端的时间  必须是服务器的时间这里用一个settimeout代替 以为时间必须统一  

                     2、开始时间,结束时间通过父组件传入,当服务器时间在这个开始时间和结束时间的范围内  参加活动按钮可以点击,并且参加过活动以后不能再参加,

         3、在组件创建的时候 同步得到现在时间服务时间差,并且在这里边设置定时器,每秒都做判断看秒杀是否开始和结束,

         4、在更新时间的函数中是否开始和结束,

         5、在computed钩子中监听disable 确定按钮是否可点击

         6、参加过活动在updated中停止定时器的计时,页面销毁的时候也停止计时

        下边是代码

        子组件  

    <template>
        <div>
            <button @click="handleClick" :disabled="disabled">
                {{btnText}}
            </button>
            <span>{{tip}}</span>
        </div>
    </template>
    
    <script>
    
        import moment from 'moment'
    
        export default {
            name: "Spike",
            props: {
                startTime: {
                    required: true,
                    validator: (val) => {
                        return moment.isMoment(val)
                    }
                },
                endTime: {
                    required: true,
                    validator: (val) => {
                        return moment.isMoment(val)
                    }
                }
            },
            data() {
                return {
                    start: false,
                    end: false,
                    done: false,
                    tip: '',
                    timeGap: 0,
                    btnText:""
                }
            },
                computed: {
                disabled() {
                    //当三个异号的时候disable返回真,不可点击,
                    // 初始化通过this.updateState确定disable的状态
                    return !(this.start && !this.end && !this.done);
                }
            },
            async created() {
                const serverTime=await this.getServerTime();
                this.timeGap=Date.now()-serverTime;//当前时间和服务器时间差
                this.updateState();
                this.timeInterval=setInterval(()=>{
                    this.updateState()
                },1000)
            },
            updated(){
                if(this.end||this.done){
                    clearInterval(this.timeInterval)
                }
            },
            methods: {
                handleClick() {
                    alert("提交成功");
                    this.done=true;
                    this.btnText="已参加过活动"
                },
                getServerTime() {
                    //模拟服务器时间
                    return new Promise((resolve, reject) => {
                        setTimeout(() => {
                            //当前时间慢10秒就是服务器时间
                            resolve(new Date(Date.now() -10 * 1000).getTime())//跟本地时间差
                        }, 0)
                    })
                },
                updateState() {
                    const now = moment(new Date(Date.now() - this.timeGap));//当前服务器时间
                    const diffStart=this.startTime.diff(now);//开始时间和服务器时间之差
                    const diffEnd=this.endTime.diff(now);//结束时间和服务器时间之差
                    if(diffStart<0){
                        this.start=true;
                        this.tip="秒杀已开始";
                        this.btnText="参加"
                    }else{
                        this.tip=`距离秒杀开始还剩${Math.ceil(diffStart/1000)}秒`;
                        this.btnText="活动未开始";
                    }
                    if(diffEnd<=0){
                        this.end=true;
                        if( !this.btnText==="已参加过活动"||this.btnText==="参加"){
                            this.tip="秒杀已结束";
                            this.btnText="活动已结束";
                        }
                    }
                }
            },
            beforeDestroy() {
                clearInterval(this.timeInterval)
            }
        }
    </script>
    
    <style scoped>
        button[disabled]{
            cursor: not-allowed;
        }
    </style>

    父组件

    <template>
        <div>
            <h1 style="color: red">设计一个秒杀倒计时的组件</h1>
            <Spike :startTime="startTime" :endTime="endTime"></Spike>
        </div>
    </template>
    
    <script>
        import Spike from './Spike'
        import moment from 'moment'
        export default {
            name: "index",
            components:{
                Spike
            },
            data(){
                return{
                    endTime:moment(new Date(Date.now()+10*1000)),
                    startTime:moment(new Date(Date.now()))
                }
            }
        }
    </script>
    
    <style scoped>
    
    </style>

    用到moment的这个关于时间操作的库

    
    
    
    有志者事竟成,破釜沉舟,百二秦关终属楚;  苦心人天不负,卧薪尝胆,三千越甲可吞吴。
  • 相关阅读:
    C语言II|博客园04
    C语言!!!博客作业03
    C语言II博客作业02
    C语言II—作业01
    deppin系统安装electron步骤及问题
    deppin20.2 频繁卡死问题已解决
    那些实用的Nginx规则
    hibernate4升级5带来的一些参数变化
    java 后台获取文件上传的真实扩展名
    eclipse 卡顿的优化办法
  • 原文地址:https://www.cnblogs.com/manIteresting/p/10659660.html
Copyright © 2011-2022 走看看