【问题标题】:Clear Interval doesn't work in VUE清除间隔在 VUE 中不起作用
【发布时间】:2017-11-09 16:40:06
【问题描述】:

我正在尝试使用 VUE.js 构建番茄钟,下面是我遇到问题的相关代码 sn-p。所以问题是 clearInterval 方法在这里似乎不起作用。

   data: {
        workTimeInMin: 1,
        breakTimeInMin: 1,
        timeRemainInMillisecond: 0,
        timerOn: false,
        rest: false
      },

      methods: {
        startOrStopTheTimer: function() {
          var self = this;
          var interval;
          if (this.timerOn){
            this.timerOn = !this.timerOn;
            window.clearInterval(interval);
            console.log("clearInterval");
          }else {
            this.timerOn = !this.timerOn;
            interval = setInterval(function(){
            console.log("123");
            if (self.timeRemainInMillisecond <= 0) {
              console.log("1");
              self.rest = !self.rest;
              if (self.rest) {
                self.timeRemainInMillisecond = self.restTimeInMin*60*1000;
              }else {
                self.timeRemainInMillisecond = self.workTimeInMin*60*1000;
              }
            }
              this.timeRemainInMillisecond = this.timeRemainInMillisecond-1000
            }, 1000);
          }
        },

You can find a live demo here.

在页面中,当我单击开始时,会调用一个 set Interval 方法。然后我点击了停止,它应该清除间隔,但它似乎没有按我的意愿工作。可以查看控制台,很容易发现一直弹出“123”,表示间隔没有清除。

在 StackOverFlow 中搜索了一段时间后,我发现如果我将变量 interval 定义为在全局上下文中,它将按我的意愿工作。但我想知道为什么会这样。

我们将非常感谢您的帮助。提前致谢!

【问题讨论】:

  • 您意识到var interval; 创建了新变量,其值为undefined
  • 使用 window.interval 全局设置值
  • @dfsq 我知道这一点。然后应该在 for 循环的 else 部分将间隔设置为 var interval = setInterval。所以我想知道为什么我不能在这里使用clearInterval
  • 您的interval 变量的作用域是方法,因此每次方法运行时您都会获得一个新变量。我会将其限定为组件——将它放在data 块中——而不是用全局变量污染window。 (这也将消除您的 timerOn 变量的需要。)
  • 我发现 this.interval 将其设置为对象,而不是 nodejs 环境中的实际 ID。所以我不得不运行clearInterval(this.interval._id)

标签: javascript jquery vue.js


【解决方案1】:

您的问题是 var interval 是每次调用函数时都声明的新函数。因此,无法访问包含对您的区间的引用的变量。

只需使用this.interval,该变量就会添加到引擎盖下组件的数据部分。

你也可以只使用这个 mixin(插件)/看看它是如何工作的: Vue interval mixin

【讨论】:

  • 这在 2019 年 12 月对我有用 - 我没有在我的 data() { } 部分声明间隔,而是将我的间隔分配给 this.interval。将其添加到数据中使其无法工作。
【解决方案2】:

您可以清除 setInterval 和 clearinterval。这是示例代码,请根据您的需要修改

if (val && !this.t) {
    this.t = setInterval(() => {
        location.reload()
    }, 10 * 1000)
} else {
    clearInterval(this.t)
}

【讨论】:

    【解决方案3】:

    我到达这个页面是因为 Vue 似乎仍然以 OP 描述的奇怪方式处理 setInterval。我尝试了上面的所有修复,发现只有两个选项有效:

    • 区间变量的全局范围(如上所述,不是理想的解决方法)
    • 使用 Vuex 来存储计时器并以通常的 Vuex 方式处理它。

    我很高兴发现使用 Vuex 绕过了这个问题,因为我一直在使用 Vuex。它并没有说明为什么会出现这个问题,但它确实为我们提供了一种前进的方式,只需做出很少的牺牲。

    因此,只需在 Vuex 状态下声明变量,使用突变来启动和停止计时器,一切都会按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多