我阅读了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
的根的第一个子项添加更多/更改参数
谢谢!
答案 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发布后,该问题将得到解决。
希望这对您有所帮助-随时询问。