watch和computed的区别

223 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、区别

先简单说下其两者区别:

computed: 可以从组件的多个数据派生出新数据

  • computed是计算属性,顾名思义也就是计算值,它更多用于计算值的场景
  • computed具有缓存性,computed的值在getter执行后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值时才会重新调用对应的getter来计算 computed适用于计算比较消耗性能的计算场景
  • 常用场景:简化行内的复杂的逻辑表达式,模板中出现太多逻辑会使得模板变得臃肿难以维护。

watch: 侦听器可以侦测某个响应式数据的变化并执行副作用

  • 更多的是「观察」的作用,类似于某些数据的监听回调,用于观察props $emit或者本组件的值,当数据变化时来执行回调进行后续操作
  • 无缓存性,页面重新渲染时值不变化也会执行

小结:

  • 当我们要进行数值计算,而且依赖于其他数据,那么把这个数据设计为computed
  • 如果你需要在某个数据变化时做一些事情,使用watch来观察这个数据变化

computed和watch的差异:

①对于关系:computed多对一(多个数据影响一个computed返回的数据);watch一对多(监听一个数据的变化,可以做多个数据的操作)

②computed是同步return出去一个值;watch中可以处理异步。

二、使用细节及详解

computed

computed和methods的差异是它具备缓存性,如果依赖项不变时不会重新计算。

Computed本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。 适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理

使用: computed可以传入一个对象,实现可读可写

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 常用写法:仅读取
    aDouble: function () {
      return this.a * 2
    },
    // 读取和设置
    aPlus: {
      // this.aPlus 时触发
      get: function () {
        return this.a + 1
      },
      // this.aPlus = 1 时触发
      set: function (v) {
        this.a 
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4

watch

watch可以传递对 象,设置deep、immediate等选项。

vm.$watch('obj', {
    // 深度遍历
    deep: true,
    // 立即触发
    immediate: true,
    // 执行的函数
    handler: function(val, oldVal) {}
})

另外watch还可以监听的可以是对象的某个属性,也可以是个表达式;监听的handler也可以是个数组:

var vm = new Vue({
    data: {
        a: 1,
        b: 2,
        obj: {
            name: 'xx'
        }
    }
    watch: {
        // 监听对象的属性
        'obj.name': function(val, oldVal) { /* ... */ },
        // 监听一个表达式
        a+b: function(val, oldVal) { /* ... */ },
        // 监听的回调是个数组,它们会被逐一调用
        b: [
          'handle1',    // methods中的方法名
          function handle2 (val, oldVal) { /* ... */ },
          {
            immediate: true,
            handler: function handle3 (val, oldVal) { /* ... */ },
            /* ... */
          }
        ],
    }
})

源码

computed的实现

ComputedRefImpl

缓存性

watch的实现

三、vue3中的变化

  1. vue3中watch选项发生了一些变化。不能监听÷点操作符外的其他表达式。
  2. reactivity API中新出现了watch、watchEffect完全可以代替目前的watch选项,且功能更加强大。