我在观看vue时遇到问题。
如何解释这种行为:在{strong>创建 test.a
属性时触发test.b
上的观察者?
vm = new Vue({
data: {
test: { a: {}, c: {} }
}
})
vm.$watch('test.a', () => {console.log('> test.a changed')})
vm.$watch('test.b', () => {console.log('> test.b changed')})
vm.$watch(() => vm.test.c, () => {console.log('> test.c changed')}, {deep: true})
setTimeout(() => {
console.log('creating: test.b')
Vue.set(vm.test, 'b', {})
}, 10)
setTimeout(() => {
console.log('changing: test.b')
vm.test.b = 1
}, 20)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
编辑:
在现实世界中,我使用深度监视程序,但在正常和深度监视程序类型中都观察到了这种行为。
创建新属性会触发所有喜欢的手表,并且在大多数情况下会触发普通手表。
答案 0 :(得分:0)
Vue.set(vm.test, 'b', {})
仅触发一次test
中的更改。
vm = new Vue({
data: {
test: { a: {}, b: {}}
}
})
vm.$watch('test.a', () => {console.log('> test.a changed', vm.test)}, {deep: true})
vm.$watch('test.b', () => {console.log('> test.b changed', vm.test.b)}, {deep: true})
setTimeout(() => {
Vue.set(vm.test, 'b', {name: 1})
}, 1000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
使用deep: true
和test: {a: {}, b: {}}
应该可以解决问题
答案 1 :(得分:0)
一种解决方案是使用返回嵌套对象的JSON的函数,而不是使用点分隔的路径:
vm.$watch(
// The first function returns the JSON representation of the object
() => JSON.stringify(vm.test.a),
// Handler
() => console.log('> test.a changed')
);
但是,对于vm.test.b
(可能在运行时未定义),则需要使用新的null-coalescing operator ??
supported by some modern browsers:
vm.$watch(
// The first function returns the JSON representation of the object
() => JSON.stringify(vm.test.b ?? {}),
// Handler
() => console.log('> test.a changed')
);
如果要向后兼容,可以使用更详细的检查,即:
vm.$watch(
// The first function returns the JSON representation of the object
() => JSON.stringify(vm.test.b === void 0 ? {} : vm.test.b),
// Handler
() => console.log('> test.a changed')
);
vm = new Vue({
data: {
test: {
a: {}
}
}
})
vm.$watch(
() => JSON.stringify(vm.test.a),
() => console.log('> test.a changed')
);
vm.$watch(
() => JSON.stringify(vm.test.b === void 0 ? {} : vm.test.b),
() => console.log('> test.b changed')
);
setTimeout(() => {
console.log('creating: test.b')
Vue.set(vm.test, 'b', {})
}, 10)
setTimeout(() => {
console.log('changing: test.b')
vm.test.b = 1
}, 20)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>