018.Watch和Computed

Posted Composition55555

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了018.Watch和Computed相关的知识,希望对你有一定的参考价值。

文章目录


01. 监听器watch

(1)作用

  • watch:用于监听data中的数据变化,只在被监听的属性值发生变化时执行

    export default 
        data() 
            return 
                number: 1
            
        ,
        watch:
            // 普通监听方法,这里表示监听data中的 number属性
            // 第一个参数表示改变后的新值,第二个参数表示改变前的旧值
            number(newVal,oldVal)
                console.log(newVal);
                console.log(oldVal);
            
        
    
    

(2)属性和方法

  • immediate:表示在组件创建后,立即监听属性,在最初绑定值的时候,设置为:immediate: true

  • handler:监听对象的时候使用,发生变化时,执行handler中的方法~

  • deep:表示深度监听对象、数组内部的属性的变化,设置为:deep: true

    export default 
        data()
            return 
                number: 1
            
        ,
        watch: 
            // 监听 number属性
            number: 
    			handler(newVal, oldVal)
                    
                ,
                immediate: true, // 立即监听
            
        
    
    

(3)监听对象

  • 可以监听对象的直接赋值操作

    • 但不能监听对象属性的添加、修改、删除

      export default 
          data() 
              return 
                  obj: 
                      a: 1
                  
              
          ,
          watch: 
              obj: 
                  handler(newVal)
                      console.log('监听到了', newVal)
                  ,
                  immediate: true
              
          ,
          created()
              // 无法监听到,因为是对属性进行的修改操作
              // 打印一次,且打印结果为修改后的值,
              this.obj.a = 2 
      
              // 可以监听到,因为是直接对 对象进行的 赋值操作
              // 打印两次(immediate立即监听会打印一次,修改时打印一次)
              this.obj =  a: 2 
          
      
      

    由于 Vue 会在初始化实例时,会对属性执行 getter/setter 转化过程

    所以属性必须在 data 对象上存在,才能让 Vue 转换它,这样才能让它是响应式的

    因此,Vue 无法检测到对象属性的添加、删除、修改等操作


    默认情况下 handler 只监听对象内部属性的引用的变化

    因此,我们只有进行赋值操作的时候,它才会监听到

  • 可以直接监听对象的某一个属性值

    • 如果这个属性是基本类型的值,就可以正常监听

      export default 
          watch: 
              'obj.a': 
                  handler(newVal)
                      console.log(newVal)
                  
              
          ,
          created()
              // 以下两个都可以监听到 打印两次
              this.obj.a = 2
              this.obj =  a:2 
          
      
      
  • 可以使用deep属性进行深度监听

    • 只能监听原有属性的变化,不能监听新增属性

    • vue 无法监听 this.$set 修改原有属性的变化

      这是因为,this.$set()就是相当于在data中对初始值进行改变

      可以触发监听,但变化体现不出来,即newVal === oldVal

    export default 
        watch: 
            obj: 
                handler(newVal)
                	console.log(newVal)
                ,
                deep: true,
                immediate: true
            
        ,
        created()
            // 进行深度监听后,直接修改属性的变化也可以监听到
            // 打印两次(因为immediate)
            this.obj.a = 2
            
            // 无法监听到 对象属性的增加
            // 打印一次,且打印结果为添加了新增属性的对象
            // 即,它只会 因immediate而执行一次 ,且打印输出 a:1,b:2
            this.obj.b = 2
            
            // 可以触发监听,但无法监听到变化
            // 打印两次,两次值都是a:2,不能体现变化
            this.$set(this.obj, 'a', 2)
        
    
    

(4)监听数组

  • 可以监听

    • 数组的直接赋值操作

    • 通过数组方法的添加、修改、删除操作

    • 通过this.$set()方法进行的数组操作

      数组方法如pop()push()等,和this.$set(arr, index, newVal)方法

      它们可以触发监听,但无法体现变化,即newVal === oldVal

  • 无法监听

    • 无法监听数组的非数组方法的添加、删除、修改操作
    • 无法监听直接通过索引值改变数组的变化
    • 无法监听直接修改数组长度的变化
    export default 
        data() 
            return 
                arr: [1]
            
        ,
        watch: 
            arr: 
                handler(newVal, oldVal) 
                    console.log('新:', newVal)
                    console.log('旧:', oldVal)
                ,
                immediate: true
            
        ,
        created() 
            // 可以监听到---直接整个数组赋值
            this.arr = [2]
            
            // 无法监听到---索引赋值、长度修改
            this.arr[1] = 2
            this.arr[0] = 2
            this.arr.length = 2
            
            // 可以触发监听,但无法监听到变化 => 即新、旧值都是一样的
            this.arr.push(2)
            this.$set(this.arr, 0, 2)
        
    
    

02. 计算属性computed

(1)计算属性的set方法

  • 计算属性可以写为一个 Object,而非 Function,只是 Function 形式是我们默认使用它的 get 方法,当写为 Object 时,我们还可以使用它的 set 方法

    computed: 
      fullName: 
        get () 
          return `$this.firstName $this.lastName`;
        ,
        set (val) 
          const names = val.split(' ');
          this.firstName = names[0];
          this.lastName = names[names.length - 1];
        
      
    
    

    当执行 this.fullName = 'Aresn Liang',computed 的 set 就会调用,firstNamelastName 就会被赋值为AresnLiang

    computed 可以依赖其它 computed,甚至是其它组件的 data

(2)区别

  • 计算属性和监听器
    • 计算属性computed是:监听依赖值的变化
      • 只要依赖值不变,都会直接读取缓存进行复用
      • 计算属性不能响应异步操作中数据的变化
      • 需要人为调用
    • 监听器watch是:监听属性值的变化
      • 只要属性值发生变化,都可以触发一个回调函数
      • 监听器可以响应异步操作中数据的变化
      • 自动触发
  • 计算属性和方法
    • methods 是一个方法,它可以接受参数,而 computed 不能
    • computed可以缓存的,methods 不会

(3)使用场景

  • 当一个属性受多个属性影响的时候就需要用到computed

  • 一条数据影响多条数据的时候就需要用watch,如搜索数据

以上是关于018.Watch和Computed的主要内容,如果未能解决你的问题,请参考以下文章

Vue computed和watch

[Vue] 计算属性Computed与函数function的异同

vue2源码-- computed 计算属性的实现

vue2源码-- computed 计算属性的实现

vue中computed和watch的用法

Vue计算属性和监听属性