【问题标题】:Vue cant watch object property setted inside for loopVue 无法观察在 for 循环中设置的对象属性
【发布时间】:2021-05-23 12:52:19
【问题描述】:

我想在 for-loop 中设置一个对象属性,并注意这些变化,但不知何故,Vue 根本不会监听 watch 属性上的所有变化。

这是我的测试代码,用于简化我的问题 (https://jsfiddle.net/hn2wepc9/)。

如果单击按钮,它应该在控制台中记录 5 行(因为 loop 方法),但它只记录 1。我不明白为什么 Vue 在我使用时根本不听所有更改Vue.set()for 循环中并尝试观察这些变化。

<div id="app">
  <button @click="loop">Button</button>
</div>
new Vue({
  el: '#app',
  data: () => {
    return {
          obj: {
            name: 'John Doe'
        }
     }
  },
  methods: {
    loop() {
      for (let i = 0; i < 5; i++) {
        Vue.set(this.obj, 'name', 'Dohn Joe ' + i);
      }
    }
  },
  watch: {
    obj: {
      deep: true,
      handler(newVal, oldVal) {
        window.console.log(newVal.name + ' - ' + new Date().toLocaleString());
      }
    }
  }
});

【问题讨论】:

  • 顺便说一句,您不需要在这里使用Vue.set,因为obj.name 已经存在于data() 的init 中。可以直接设置:this.obj.name = 'Dohn Joe ' + i.

标签: vue.js vuejs2


【解决方案1】:

默认情况下,观察者是异步运行的(在 next 宏标记中)作为性能优化。我认为动机是假设观察者只关心最近的变化。

您可以通过设置sync 标志(多个undocumented watch flags 之一)将观察程序配置为同步:

watch: {
  obj: {
    sync: true
  }
}

updated fiddle


作为参考,在 Vue 3 中,该标志被称为 flushprepostsync 作为可能的值。见Effect flush timing

【讨论】:

  • 这是在 Vue 文档中吗?我阅读了文档,但没有发现任何关于 sync 道具的信息。非常感谢。
  • 不,它是several undocumented flags 之一。
  • 刚刚找到的这里的评论,根据这篇帖子forum.vuejs.org/t/…看来sync api是不公开的
猜你喜欢
  • 1970-01-01
  • 2020-02-04
  • 2019-06-02
  • 1970-01-01
  • 2021-03-30
  • 2013-03-01
  • 1970-01-01
  • 2022-01-26
  • 1970-01-01
相关资源
最近更新 更多