【问题标题】:Vue.js watch fires despite no apparent changes in data尽管数据没有明显变化,Vue.js watch 还是会触发
【发布时间】:2021-11-14 05:56:34
【问题描述】:

关于 Vue 2 的一个问题,我已经没有什么想法了,这会导致手表触发,据我所知,它不应该触发。当我长时间轮询 API 并使用新的、可能更改的数据更新数据时,就会发生这种情况。我希望手表在数据更改时触发,但显然不是在没有数据更改的情况下。

让我把它浓缩为代码的关键部分。这是数据:

data() {
    return {
        ffGameState: {
            errors: {
                team1: [false, false, false]
            }
        }
    }
}

这是手表:

watch: {
    "ffGameState.errors.team1": {
        deep: true,
        handler: function(val, oldVal) {
            console.log("change detected")
            console.log(val)
            console.log(oldVal)
        }
    }
}

最后是检索数据并更新 ffGameState 对象的方法(它在创建时触发):

loadFfGameState() {
    var vm = this
    this.$http
    .get("/gamestates/ff")
    .then(response => {
        vm.ffGameState = response.data
    })
    .then(() => {
        setTimeout(() => this.loadFfGameState(), 100)             
    })
}

所有这些都会导致每次获取数据时(即每 100 毫秒)都会触发手表,请查看浏览器的日志输出:

change detected
AudienceScreen.vue?57f6:272 (3) [true, true, true, __ob__: Observer]
AudienceScreen.vue?57f6:273 (3) [true, true, true, __ob__: Observer]

第一眼我能看出的唯一区别是 __ob__.dep.id 发生了变化,但我不认为这会导致手表触发。

我尝试过的事情:

  • 直接使用this,而不是定义var vm = this
  • 使用vm.$set(vm, "ffGameState", response.data)

另一个可能有用的信息是 lodash 的 _.isEqual(val, oldVal) 返回 true。

感谢您的帮助,非常感谢!

【问题讨论】:

  • 这是正确的行为。 watch 会在被监视对象设置 为新实例时触发。 loadFfGameState() 将ffGameState 设置为一个全新的实例,这会触发深度观察器,因为子属性数组是新的。如果在这种情况下需要防止对相同的值发生动作,则需要手动进行比较。
  • 谢谢。但不知何故,它似​​乎没有用 - 这是否意味着只能观察简单的对象类型?那么deep: true 选项有什么作用呢?可能我错过了什么。
  • 抱歉发了两次帖子,但我想我明白了。因此,只要其中一个字段更改,例如通过this.ffGameState.errors.team1 = [true, true, true] 为其分配一个新值,它将触发手表。但如果整个对象被替换,则不会。这种理解正确吗?无论如何,非常感谢,我现在只是使用 lodash,它工作得很好。只是认为它应该首先与手表一起使用。
  • @tony19:如果您将此作为正确答案,我可以接受。完成后我将删除此评论。

标签: vue.js vuejs2


【解决方案1】:

我认为您需要像这样使用computed 属性来分隔team1:

computed: {
    team() {
        return this.ffGameState.errors.team1
    }
}

然后观察这个计算属性以处理仅与 team1 相关的更改:

watch: {
    team: {
        deep: true,
        handler: function(val, oldVal) {
            console.log("change detected")
            console.log(val)
            console.log(oldVal)
        }
    }
}

【讨论】:

  • 谢谢,但恐怕这不会导致预期的行为。
猜你喜欢
  • 2016-08-01
  • 2020-04-10
  • 1970-01-01
  • 2012-06-30
  • 2016-07-17
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多