const Demo = Vue.extend({
template: `<div>
<button @click="onSetOther">未显示属性赋值会不会导致watch执行</button>
<button @click="onSetInputValue">属性赋值</button><br />
<input v-model="objComputed.inputValue"></input>
</div>`,
data() {
return {
obj: {
inputValue: '',
otherValue: '',
}
}
},
computed: {
objComputed: {
get() {
console.log('getter', this.obj)
return this.obj
},
set(v) {
console.log('setter', v)
this.obj = v
}
}
},
watch: {
obj: {
deep: true,
handler(v, oldV) {
console.log('v: %o; oldV: %o', v, oldV)
}
}
},
methods: {
onSetInputValue() {
// 这种属性赋值只会触发 objComputed 的 getter,不会触发 setter
// 因为 watch deep="true",所以回调会执行,但此时因为this.obj 和 this.objComputed 是同一个对象,
// 所以 v.inputValue 和 oldV.inputValue 是相同
this.objComputed.inputValue = 'abc'
// 如果需要触发 objComputed 的 setter,需要像下面这样写
// this.objComputed = {
// ...this.objComputed,
// inputValue: 'abc'
// }
},
onSetOther() {
// 这里赋值会导致 watch obj 回调执行
// 回调执行过程会获取 this.objComputed 的值,触发 getter
this.objComputed.otherValue = '23231'
}
}
})
const vm = new Vue({
el: '#app',
components: {
Demo
}
})
<div id="app">
<Demo />
</div>