vue 設計一個倒計時秒殺的組件

簡介:vue

倒計時秒殺組件在電商網站中層出不窮  不過思路萬變不離其蹤,我本身根據其餘資料設計了一個vue版的服務器

核心思路:一、時間不能是本地客戶端的時間  必須是服務器的時間這裏用一個settimeout代替 覺得時間必須統一  async

                 二、開始時間,結束時間經過父組件傳入,當服務器時間在這個開始時間和結束時間的範圍內  參加活動按鈕能夠點擊,而且參加過活動之後不能再參加,函數

     三、在組件建立的時候 同步獲得如今時間服務時間差,而且在這裏邊設置定時器,每秒都作判斷看秒殺是否開始和結束,網站

     四、在更新時間的函數中是否開始和結束,ui

     五、在computed鉤子中監聽disable 肯定按鈕是否可點擊this

     六、參加過活動在updated中中止定時器的計時,頁面銷燬的時候也中止計時spa

    下邊是代碼設計

    子組件  code

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

相關文章
相關標籤/搜索