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

时间:2018-11-30 11:56:44

标签: vue.js 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,但实际上并没有删除。

是否有一种方法不替换键/值对,而是向ID为newID的根的第一个子项添加更多/更改参数

谢谢!

3 个答案:

答案 0 :(得分:2)

当您想为现有对象(而不是直接为数据)定义新属性时,需要Vue.set(),此函数会将新属性分配给内置观察者,然后它也会变得有反应性。

所有这些都在文档中进行了解释: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>

如您在小提琴中看到的那样,新属性变得反应灵敏并被显示。

答案 1 :(得分:1)

尝试:

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

答案 2 :(得分:1)

解决方案:将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发布后,该问题将得到解决。

希望这对您有所帮助-随时询问。