Vue的computed与watch

680 阅读3分钟

Vue的computed与watch

computed

  1. 概念:计算属性,顾名思义就是计算得到的属性。

  2. 计算属性有2种形式,一种是带有返回值的函数,另一种是一个拥有getter/setter的对象。

    computed: {
        // 仅读取
        aDouble: function () {
          return this.a * 2
        },
        // 读取和设置
        aPlus: {
          get: function () {
            return this.a + 1
          },
          set: function (v) {
            this.a = v - 1
          }
        }
    
  3. 计算属性的使用和普通的data一样,都能够使用插值语法插入到模板中。

  4. computed有缓存功能,当多次调用但是其依赖没有改变时,computed会从直接从缓存中取值。

watch

  1. 概念:监听。当所监听的数据发生变化是执行指定的函数。和computed很类似,但是使用的环境不太相同。

  2. watch的语法:

    watch:{
        a:function(newValue,oldValue){...}, // 常规用法,使用使用一个函数
        b(newValue,oldValue){...} ,// 常规用法的ES6升级
        c:{ // 使用对象声明
            handler:'methodName' ,// handler:处理函数,可以是method中的方法,也可以直接使用一个函数
            deep: true// deep:深入监听
            immediate: true // immediate:初次变化监听
        },
        d:{
      		handler:function(newValue,oldValue){...} ,// handler也可以直接使用一个函数
            immediate:true
        }
        e:[ // 监听可以有多个处理函数
     		'handler1', // methods中的方法
            function handler2(new,old){...},
            {
                 handler:   function handler3(new,old){...}
            }
        ],
        // 监听3级以上的属性(根数据对象为1级)
        // 注意这里的冒号
        'e.f':function(newvalue,oldvalue){..}
    }
    

注意,不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

watcher函数默认有newValue,oldValue两个参数

  1. watch的deep&immediate选项

    • deep选项:监听属性内部数据,即深入监听。

      watch:{
          obj:{
              handler:'myHandler',
              deep:true
          }
      }
      // 当deep选项为true时,obj内部数据的变化也会被监听
      
    • immediate:在选项参数中指定 immediate: true将立即以表达式的当前值触发回调。

  2. 编程式操作watch,vm.$watch

    语法:

    vm.$watch( expOrFn, callback, [options] )
    // 示例:
    // expOrFn为字符串时,监听Vue实例data中的'a.b.c'
    vm.$watch('a.b.c', function (newVal, oldVal) {...})
    // expOrFn为函数时,监听返回值
    vm.$watch(
        function(){
            // 这里监听的是 this.a + this.b 的值,而不是这两个单独的数据
            // 这个效果类似监听一个未被定义的computed有点多此一举
            return this.a + this.b
        },
        function(newVal,oldVal){...} // 处理函数,分别是 this.a + this.b 的新值和旧值
    )
    
    // vm.$watch的返回值,返回一个取消监听的函数
    // 监听'a.b.c'
    let unwatch =vm.$watch('a.b.c', function (newVal, oldVal) {...}) 
    // 取消监听'a.b.c'
    unwatch()
    
  3. watch怎么判断数据是否改变了?

    简单类型看值,复杂类型看地址(有时候对象看着一样但他们的地址不同,这也是变化了),联系内存图理解。

computed VS watch

  1. computed是计算属性,可以像data一样使用,根据依赖的变化进行属性计算,有缓存功能,只有在依赖变化时才会重新计算,多次调用时不会重复计算,而是从缓存中取值。
  2. watch是数据监听,能够监听数据,当数据发生变化的时候触发处理函数的调用。
  3. 对比:
    • computed像是watch的常用功能的独立实现,我们可以通过watch来实现computed的功能,但是比起直接使用computed要麻烦很多。
    • 在功能使用上,通常只会把computed当作普通的属性来使用,而当要实现更多更复杂的操作时使用watch会更合适。