Watch 和 Computed 有什么区别

技术 7月 16, 2020

基本用法

/** watch */
watch: {
  firstName: function (val) {
    this.fullName = val + ' ' + this.lastName
  },
  lastName: function (val) {
    this.fullName = this.firstName + ' ' + val
  }
}

/** computed */
computed: {
  now: function () {
    return Date.now()
  }
}

可以发现, watch  和 computed 的基本写法基本一致(抛去特殊的写法)。
都是以 key: function() { [code] } 为基本结构。

从功能上来说


watch 是监听一个值,并对其变化作出响应
computed 是提供一个基于多个响应值的计算得出来的结果

从原理上来说


watchcomputed 在 Vue 源码内实际上都是 Watcher 对象,其中主要的区别是初始化 Watcher 时提供的参数的区别。

  1. expOrFn ,expOrFn 参数主要提供的是需要做依赖收集的表达式或者函数,表达式最终在 Watcher 构造函数内部最终还是会转换成函数,所以可以总结 expOrFn 提供的是需要做依赖收集的函数

  2. watch 提供的 expOrFn 是一个 key 值参数,比如 key1.key2.key3 ,最终在 Watcher 内部会被转换为 function(context) { return context[key1][key2][key3] }

  3. computed 提供的则是一个完整的函数

  4. lazy , lazy 参数的主要在于决定,是否在监听的值发生的变化后立即响应,并且是否会在初始化的时候就去收集依赖

    1. watch 是默认值 false ,默认直接响应,并在初始化的时候就去收集依赖,计算结果。
    2. computed 是手动传入的 true,不会在监听的值发生变化后直接响应,只在需要获取当前值的时候再去计算依赖收集得到结果。
  5. deep , deep 参数主要决定是否深度的去收集依赖,会去递归的遍历 expOrFn 得到的结果,如果结果并不是响应式的数据,即便设置了 deep 也没有作用,所以仅对 watch 有作用

    1. watch 是手动传入的 true ,在初始化或者更新数据后,会对结果进行深度遍历,从而会进行深度的依赖收集
    2. computed 为默认值 false

参考

Pengsha Ying

逝者如斯,故不舍昼夜