考虑如下两段代码:
<template id="my-app">
<h2>{{obj.message}}</h2>
<span style="font-size: 24px">旧值:{{oldValue}} 新值:{{newValue}}</span>
<br />
<button @click="changeMsg">修改msg</button>
</template>
const App = {
template: "#my-app",
data() {
return {
obj: { message: "Hello World" },
newValue: "",
oldValue: "",
};
},
methods: {
changeMsg() {
this.obj.message = "Goodbye World";
},
},
watch: {
obj: {
handler(newObj, oldObj) {
this.oldValue = oldObj.message;
this.newValue = newObj.message;
},
deep: true,
},
},
mounted() {
this.oldValue = this.obj.message;
},
};
页面预览如下:
此时点击button执行changeMsg函数后,预期得到旧值为'Hello World',新值为'Goodbye World', 但实际点击后,newObj和oldObj为同一个对象,如下图所示。
解决这个问题,可以考虑在computed中添加Data属性对obj对象进行深拷贝,再由watch监听Data间接监听obj变化执行handler,如下示代码。
computed: {
Data() {
//深拷贝原obj
return JSON.parse(JSON.stringify(this.obj))
}
},
watch: {
Data: {
handler(newObj, oldObj) {
this.oldValue = oldObj.message;
this.newValue = newObj.message;
},
deep: true,
}
},
效果如下图所示: