返回

看破watch失效的迷雾,拨开云层见真相

前端

一、watch失效的常见场景

1. 引用类型监测

watch默认只监测基本类型数据的变化,对于引用类型数据,如对象和数组,watch无法检测到其内部属性的变化。

const obj = {
  name: 'John',
  age: 30
}

const vm = new Vue({
  data() {
    return {
      obj: obj
    }
  },
  watch: {
    obj: {
      handler(newVal, oldVal) {
        console.log('obj changed')
      },
      deep: true // 深度监测
    }
  }
})

vm.obj.name = 'Mary' // 不会触发handler函数

解决方案:

在watch选项中,使用deep: true选项开启深度监测。这样,watch将不仅监测引用类型数据的本身变化,还会监测其内部属性的变化。

2. 数组监测

watch默认对数组的监测也存在局限性。当数组发生push、pop、shift、unshift等操作时,watch可以检测到数组的变化,但当数组中的元素发生变化时,watch无法检测到。

const vm = new Vue({
  data() {
    return {
      arr: [1, 2, 3]
    }
  },
  watch: {
    arr: {
      handler(newVal, oldVal) {
        console.log('arr changed')
      }
    }
  }
})

vm.arr[0] = 4 // 不会触发handler函数

解决方案:

对于数组监测,可以使用Vue.js提供的splice、push、pop、shift、unshift等方法来修改数组,这些方法会触发数组的更新,从而触发watch的handler函数。

3. 异步更新

watch默认是异步执行的,这意味着在数据更新后,watch的handler函数不会立即执行,而是会在下一个事件循环中执行。如果在handler函数中使用了vm.data的属性,可能会出现数据不一致的情况。

const vm = new Vue({
  data() {
    return {
      count: 0
    }
  },
  watch: {
    count: {
      handler(newVal, oldVal) {
        console.log('count changed to', newVal)
        this.count++ // 会输出count changed to 1,而不是2
      }
    }
  }
})

vm.count++ // 触发count更新

解决方案:

可以使用immediate: true选项来让watch的handler函数在数据更新后立即执行。

二、结语

通过本文的分析,您应该已经对watch失效的常见场景和解决方案有了深入的了解。在使用watch时,一定要注意这些失效场景,并采取相应的措施来避免它们。希望本文能帮助您更好地使用Vue.js的watch功能,开发出更强大的应用程序。