很多人习惯用watch,但是却很少有人知道watch的真正触发条件。如果不是对vue原理了如指掌,请谨慎使用watch。

示例1,下面会触发watch 吗?

<script>
  new Vue({
    data() {
      return {
        city: {id: 1, name: 'Beijing'}
      }
    },
    watch: {
      city() {
        console.log('city changed')
      }
    },
    created() {
      this.city = {id: 1, name: 'Beijing'}
    }
  })
</script>

会触发,因为在created方法里面重新给city赋值了一个对象,city前后的指向不同了

示例2:

<script>
  new Vue({
    data() {
      return {
        city: {id: 1, name: 'Beijing'}
      }
    },
    watch: {
      city() {
        console.log('city changed')
      }
    },
    created() {
      this.city.name = 'Shanghai'
    }
  })
</script>

不会触发, 因为created方法执行之后, city的指向没有变
如果我们期望捕获这种更新,应该这样写代码:

watch: {
    city: {
        handler: () => console.log('city changed'),
        deep: true
    }
}

将选项deep设为true能让vue捕获对象内部的变化。
下面讨论一下watch一个数组:

<script>
new Vue({
    el: '#body',
    data() {
        return {
            cities: ['Beijing', 'Tianjin']
        }
    },
    watch: {
        cities() {
            console.log('cities changed')
        }
    }
})
</script>

那下面哪些操作会触发cities的watch回调呢?

this.cities = ['Beijing', 'Tianjin']
this.cities.push('Xiamen')
this.cities = this.cities.slice(0, 1)
this.cities.pop();
this.cities.sort((a,b)=>a.localeCompare(b));
this.cities[0] = 'Shenzhen'
this.cities.splice(0, 1)
this.cities.length = 0

答案是只有最后三行不会触发。

Logo

前往低代码交流专区

更多推荐