vue setInterval 遇坑指南 及解决方案

好久没更新过博客了,最近小编遇到了一个经典的vue bug , 这里就把这个脱坑指南,给大家分享一下,闲话不多说,上代码!

  mounted() {
            this.timer = setInterval(() => {
                this.timeout_ = this.timeout_ - 1
                this.percent = (this.timeout_ / this.timeout) * 100
                log.info('this.timeout_',this.timeout_)
                if (this.timeout_ < 1) {
                         clearInterval(this.timer)
                         this.$emit('return-hom')   //  往上透一个事件 用来进行 倒计时结束   
                }
            }, 1000)
        },

   beforeDestroy() {
            clearInterval(this.timer)
        }     

情况是这样的 我这里有个结合倒计时做的进度条,要在倒计时结束清除掉这个倒计时,并且跳转到指定页面。之前这个代码是写好在另外一个组件的 能正常使用, 我直接复制到另外一个新的组件里面用,结果发现这个 定时器并不能销毁掉。我就在之前那个组件去试 发现却可以准确销毁, 哪怕粘贴到浏览器console 里面去调试 也是正常的,就是不能放到这个新的组件里面。

解决思路:

起初怀疑这个this.timer 并不是一个全局变量,所以在beforeDestroy 钩子函数里面,并未找到这个定时器,所以导致清除失败(注:一般清除不掉,大多都是这个原因);直到在 data 里面定义过这个变量,这里重新赋值(注意除了这里赋值,其他地方不要去修改这个值,否则也会造成开启之后清除不了)。

最后还是不能成功。

第二种解法:使用全局变量

 window.timer = setInterval(() => {
        console.log(window.timer);

      }, 1000);
destroyed() {
      clearInterval(window.timer);
    },

结果: 任然解决不掉。

第三种解法:

      const timer = setInterval(() => {
        console.log(timer);
      }, 1000);

      this.$once('hook:beforeDestroy', () => {
        clearInterval(timer);
      })

结果: 清除不掉

最终解法:

    this.timer =  window.setInterval(() => {
        this.timeout_ = this.timeout_ - 1
        this.percent = (this.timeout_ / this.timeout) * 100
        if (this.timeout_ < 1) {
          window.clearInterval(this.timer)
          // this.timer = null;
          vEvents.$emit('got-home')  
        }
    }, 1000)

解决猜测:我们都知道,这个试vue里面经典的坑,基本上都会遇到。上面的各种解题方法并不是说不管用,只是在这里小编应该是挂载的时候把这个计时器挂载到vue实例上了,而清除的时候 没等找到vue 上面的这个 计时器,就在其他地方找到了this.timer这个值,所以clearInterval(this.timer) 这行代码,并没有准确的清除掉我创建的这个计时器。 我这里把它直接挂载到window 这个最底层的实例上,清除又指定从这里清除。 所以能精确的清除掉这个计时器。

Logo

前往低代码交流专区

更多推荐