用Vue做一个倒计时

用Vue写一个倒计时。

倒计时嘛一想就很容易啊。每一秒减一不就行了嘛。那我直接就

setInterval(function(){ a = a - 1},1000);

但是setInterval函数不一定准时的,会有少许的偏差。

为什么setInterval和setTimeout会有偏差呢?

进程与线程的一个简单解释

什么是 Event Loop?

JavaScript中setInterval不能正确延时?

所以我们不能用延时-1的这种方式来进行倒计时。我们就需要一个更精确的东西来进行倒计时就是Date()。

此处插一个Date()的小用法

(此方法适用于60分钟以内的倒计时)

Date(num) 会返回一个距离UTC(Coordinated Universal Time)num微妙长度的时间戳。

这里会有时区的问题,所以我们东八区的UTC时间会是8点。所以这个方法目前只适用于60分钟以内的计时,等我成归来我看看怎么改。

WX20171121-001331@2x.png

此处返回一个跟UTC相差10分钟的时间戳。

通过getMinutes()方法跟getSeconds()方法,就可以获取到分钟和秒,要是只进行60分钟以内的倒计时的话,用这种方式取分钟和秒钟的也是一个挺方便的方法,免去了格式化一些字符串的操作。

那么我们现在确定的就是如何展示倒计时,我们先把主体的代码写一下

<html>
    <head>
        <meta charset="utf-8">
        <title>countdown</title>
    </head>
    <body>
        <div id="app-countdown">
            
            <br>
            <input type="button" value="开始倒计时">
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            var countdown = new Vue({
                el: "#app-countdown",
                data: {
                    minutes: "",
                    seconds: "",
                },
                methods: {
                },
            })
        </script>
    </body>
</html>

这样子应该差不多了

我们知道应该怎么展示时间之后,我们下一个问题就是,展示多少时间了。上文说了setInterval是一个不准确的函数,所以我们也不能setInterval延时1000毫秒然后展示的时间 - 1000ms,这样子肯定是不准确的。那我们需要怎么找出精确的1000ms呢。

假定我们需要倒计时6秒(6000毫秒),我们使用Date()来获取当前的时间,然后可以用

var rootTime = 6000 + (+new Date()) //获取倒计时完毕的时间。

然后通过不断刷新

var restTime = time - new Date() //获取距离6秒后还剩多少微妙

然后放到上述的展示技巧种,就可以获取一个精确的倒计时。

var time = new Date(restTime);
var minutes = time.getMinutes();//倒计时展示分钟数
var seconds = time.getSeconds();//倒计时展示秒钟数

附上总的代码

<html>
    <head>
        <meta charset="utf-8">
        <title>countdown</title>
    </head>
    <body>
        <div id="app-countdown">
            
            <br>
            <input type="button" @click="countdownTimer" value="开始倒计时">
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <script>
            var countdown = new Vue({
                el: "#app-countdown",
                data: {
                    time: "",
                    restTime: 5000,
                    rootTime: "",
                    minutes: "",
                    seconds: "",
                    timer: "",
                },
                methods: {
                    countdownTimer: function () {
                        this.rootTime =  +new Date();
                        this.timer = window.setInterval(this.countdown, 100);
                    },
                    countdown: function () {
                        this.time = new Date((this.restTime + this.rootTime) - new Date());
                        this.minutes = (this.time.getMinutes() < 10 ? "0" + this.time.getMinutes() : this.time.getMinutes());
                        this.seconds = (this.time.getSeconds() < 10 ? "0" + this.time.getSeconds() : this.time.getSeconds());
                        if(this.time <= 0)
                        {
                            this.minutes = "00";
                            this.seconds = "00";
                            clearInterval(this.timer);
                        }
                    }
                },
            })
        </script>
    </body>
</html>

还需要不断的学习啊