Vue Reactivity:为啥替换对象的属性(数组)不会触发更新
Posted
技术标签:
【中文标题】Vue Reactivity:为啥替换对象的属性(数组)不会触发更新【英文标题】:Vue Reactivity: Why replacing an object's property (array) does not trigger updateVue Reactivity:为什么替换对象的属性(数组)不会触发更新 【发布时间】:2020-09-17 08:06:47 【问题描述】:我有一个 Vue 应用程序,我正在尝试在 Mapbox API 上制作一个瘦包装器。我有一个包含一些简单 geojson 数据的组件,当更新该数据时,我想在地图上调用渲染函数以使用该新数据更新地图。一个 Vue 观察者应该能够做到这一点。但是,当数据发生变化时,我的观察者不会被调用,我怀疑这是 vue 反应性无法捕捉到的情况之一。我知道我可以使用this.$set
轻松解决这个问题,但我很好奇为什么这不是一个被动更新,即使根据我对规则的理解它应该是。这是相关的数据模型:
data()
return
activeDestinationData:
type: "FeatureCollection",
features: []
然后我有一个观察者:
watch:
activeDestinationData(newValue)
console.log("Active destination updated");
if (this.map && this.map.getSource("activeDestinations"))
this.map.getSource("activeDestinations").setData(newValue);
,
最后,在我的应用程序逻辑中,我通过将数组完全重新分配给具有一项的新数组来更新 activeDestination 上的功能:
// Feature is a previously declared single feature
this.activeDestinationData.features = [feature];
由于某种原因,观察者永远不会被调用。我读到了一些反应性“陷阱”here,但这两种情况都不适用于这里:
Vue 无法检测到数组的以下更改:
当您直接使用索引设置项目时,例如vm.items[indexOfItem] = newValue
当您修改数组的长度时,例如vm.items.length = newLength
我在这里遗漏了什么导致反应不发生?对于预期行为this.set()
是我唯一的选择还是有更优雅的解决方案?
【问题讨论】:
【参考方案1】:如果你需要观察一个深层结构,你必须写一些参数
watch:
activeDestinationData:
deep: true,
handler() /* code... */
您可以在那里阅读更多信息 -> https://vuejs.org/v2/api/#watch 希望对你有帮助:)
【讨论】:
【参考方案2】:因为默认 vue 会进行浅比较,并且由于您正在改变数组而不是替换,因此它的参考值是相同的。您需要在更新其内容时传递一个新的数组引用,或者传递选项deep: true
以查看嵌套值的变化:
watch:
activeDestinationData:
handler(newValue)
console.log("Active destination updated");
if (this.map && this.map.getSource("activeDestinations"))
this.map.getSource("activeDestinations").setData(newValue);
,
deep: true
【讨论】:
以上是关于Vue Reactivity:为啥替换对象的属性(数组)不会触发更新的主要内容,如果未能解决你的问题,请参考以下文章