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发布后得到解决
希望这对您有所帮助,如果您需要任何说明 - 请随时提问。
我阅读了 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发布后得到解决
希望这对您有所帮助,如果您需要任何说明 - 请随时提问。