Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?
Posted
技术标签:
【中文标题】Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?【英文标题】:Vue: Do watchers on deep nested objects log oldVal and newVal? 【发布时间】:2021-05-31 11:34:26 【问题描述】:我在深层嵌套对象上有一个watcher
。我正在使用Vue.set()
向对象添加反应属性。这触发了观察者,但 newVal 和 oldVal 控制台日志都显示了已经添加了新属性的数据,而不是 oldVal 显示了在添加新属性之前它是什么。
<button @click="addData">Add</button>
data()
return
myData:
time:
,
watch:
myData:
handler(newVal, oldVal)
console.log("NEW", newVal);
console.log("OLD", oldVal);
,
deep: true
,
methods:
addData()
this.$set(this.myData.time, 'other','testing')
【问题讨论】:
这能回答你的问题吗? Vuejs get old value when on change event API 文档中提到你不能:VueJS 不保留对对象前值的引用:vuejs.org/v2/api/#vm-watch 这能回答你的问题吗? Vue watch array push same old and new values 【参考方案1】:正如@Terry 所说,vue 不保留对oldValue
的引用,看看docs 是怎么说的:
注意:当改变(而不是替换)对象或数组时,旧值将与新值相同,因为它们引用相同的对象/数组。 Vue 不保留预突变值的副本。
有一些方法可以解决这个问题:
使用原生 javascript
添加一个计算属性,将您的数据属性转换为JSON string
。
在 Watch
函数上使用 JSON.parse
将字符串转换回对象。
data()
return
myData:
time:
,
computed:
computedMyData()
return JSON.stringify(this.myData);
,
watch:
computedMyData:
handler(newValJSON, oldValJSON)
let newVal = JSON.parse(newValJSON),
oldVal = JSON.parse(oldValJSON);
console.log("NEW", newVal);
console.log("OLD", oldVal);
,
deep: true
,
methods:
addData()
this.$set(this.myData.time, 'other','testing')
小提琴:https://jsfiddle.net/mLbuf6t0/
使用LODASH
使用cloneDeep
函数添加一个计算属性,该属性从您的数据属性返回一个深度克隆。
data()
return
myData:
time:
,
computed:
computedMyData()
return _.cloneDeep(this.myData)
,
watch:
computedMyData:
handler(newVal, oldVal)
console.log("NEW", newVal);
console.log("OLD", oldVal);
,
deep: true
,
methods:
addData()
this.$set(this.myData.time, 'other','testing')
小提琴:https://jsfiddle.net/mLbuf6t0/2/
【讨论】:
以上是关于Vue:深层嵌套对象上的观察者会记录 oldVal 和 newVal 吗?的主要内容,如果未能解决你的问题,请参考以下文章
谈谈 Vue shallowRef 和 shallowReactive