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的這個關於時間操作的庫

 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM