首页 > 解决方案 > Vue watcher triggered on creating sibling property

问题描述

I'm experiencing problems with vue watchers.

How to explain such behavior: watcher on test.a is triggered on creating test.b property?

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>

EDIT:

In real world I use deep watchers, but such behavior was observed for both: normal and deep watcher types.

Creating new property triggers all sibbling deep watches and in most cases normal watches.

标签: vue.js

解决方案


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: {}}应该解决问题


推荐阅读