Vue:如何在 v-for 中执行反应式对象变化检测?

Vue: How to perform reactive object change detection in v-for?

我阅读了 this 文档,但无法使用建议的解决方案。

我有一个 v-for 对象循环。这些对象会随着时间的推移而动态变化,我需要这种变化在 v-for 循环中以反应方式显示。

<b-row lg="12" v-for="data in objects" :key="data.id">
    <div v-if="data.loading">
      loading...
      {{data.loading}}
    </div>
    <div v-else>
      loaded, done
      {{data.loading}}
    </div>
</b-row>

在我的方法中,我有一个 for 循环,它为每个对象下载数据并像这样更改对象值:

for(var i = 0; i<response.ids.length; i++){
    var newId = response.ids[i].id
    this.objects.newId = {"loading":true, "id": newId}

    downloadSomething(newId).then(res => {
        this.objects.newId = res[0]         //<-- this change needs to be shown reactively.
    })
}

根据 Vue 文档,对象更改不是反应性的:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` is now reactive

vm.b = 2
// `vm.b` is NOT reactive

Vue 提出了一些这样的解决方法:

Vue.set(vm.userProfile, 'age', 27)

更新

但对于我的情况,这只是在具有相同ID的对象中创建了一个新参数并创建了重复键警告和其他问题。

我也在Vue.set之前尝试了Vue.delete,但它实际上并没有删除。

有没有办法不替换key/value对而是将more/change参数添加到ID为newID

的根的第一个子节点

谢谢!

你需要 Vue.set() 当你想定义一个 new 属性 到一个现有的对象(而不是直接到数据),这个函数将分配新的 属性 给内置的观察者,它也会变成反应性的。

其全部在文档中进行了解释:https://vuejs.org/v2/guide/reactivity.html

在你的情况下,这似乎是你所需要的一切。在我的示例中:https://jsfiddle.net/efrat19/eywraw8t/484131/ 一个异步函数获取数据并定义一个新的 属性 来包含响应。

new Vue({
  el: "#app",
  data: {
    objects:{
    property1:12
    }
  },
  methods: {
    fetchDataAndAddProperty(response){
        fetch('https://free.currencyconverterapi.com/api/v6/countries').then(res =>
      res.json()).then(data => Vue.set(this.objects,'property2',data))
    }
  }
})

和模板:

<div id="app">
<div lg="12" v-for="(val,key,index) in objects" :key="index">
    {{key}}:{{val}}
</div>
<button @click="fetchDataAndAddProperty()">fetch</button>
</div>

如您在 fiddle 中所见,新的 属性 变为反应式并显示。

试试看:

downloadSomething(newId).then(res => {
    this.$set(this.objects, 'newId', res[0])
})

解决方案:this.objects.newId = res[0] 替换为 this.$set(this.objects, 'newId', res[0]) 应该可以。

说明: this.$set 只是 Vue.set 的别名,在任何 Vue 实例中都可用。请记住,示例中的 vm(代表视图模型)与 this 相同,等于 Vue 组件实例。同样由于 ES5 JS 限制,您必须通过 Vue.set/this.$set 显式设置对象的属性才能手动触发重新渲染。这个问题会在Vue 3.0发布后得到解决

希望这对您有所帮助,如果您需要任何说明 - 请随时提问。