• Vue的computed和watch的区别是什么?


    一、computed介绍

    computed 用来监控自己定义的变量,该变量在 data 内没有声明,直接在 computed 里面定义,页面上可直接使用。

    //基础使用
    {{msg}}
    <input v-model="name" /> 
    
     //计算属性 
    computed:{
     msg:function(){
      return this.name
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在输入框中,改变 name 值得时候,msg 也会跟着改变。这是因为 computed 监听自己的属性 msg,发现 name 一旦变动,msg 立马会更新。

    注意:msg 不可在 data 中定义,否则会报错。

    1.1、get 和 set 用法

    <input v-model="full" ><br>
    <input v-model="first" > <br>
    <input v-model="second" > 
    
    data(){
     return{
      first:'美女',
      second:'姐姐'
     }
    },
    computed:{
     full:{
      get(){ //回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
       return this.first + ' ' + this.second
       },
       set(val){ //监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据
        let names = val.split(' ')
        this.first = names[0]
        this.second = names[1]
      }
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    get 方法:first 和 second 改变时,会调用 get 方法,更新 full 的值。

    set 方法:修改 full 的值时,会调用 set 方法,val 是 full 的最新值。

    1.2、计算属性缓存

    我们通过方法,拼接数据,也可以实现该效果,代码如下。

    <div> {{ full() }} </div>
    
    data(){
     return{
      first:'美女',
      second:'姐姐'
     }
    },
    methods:{
     full(){
     return this.first + ' ' + this.second
     }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    一个页面内,数据有可能多次使用,我们把 computed 和 method 两个方法放一起实现,并把这个数据在页面内多次引用,试看以下效果。

    <div>
      computed计算值:
      {{full}} {{full}} {{full}} {{full}}
    </div>
    
    <div>
      methods计算值:  {{fullt}} {{fullt}} {{fullt}} {{fullt}}
    </div>
    
    data(){
     return{
      first:'美女',
      second:'姐姐'
     }
    },
    computed:{
     full:function(){
      console.log('computed')
      return this.first + ' ' + this.second
     }
    },
    methods:{
     fullt(){
      console.log('方法')
      return this.first + ' ' + this.second
     }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    运行结果为:

    在这里插入图片描述

    根据结果,我们不难发现,根据方法获取到的数据,使用几次就需要重新计算几次,但计算属性不是,而是基于它们的响应式依赖进行缓存的,之后依赖属性值发生改变的时候,才会重新计算。由于它计算次数少,所以性能更高些。

    二、watch介绍

    watch 是监测 Vue 实例上的数据变动,通俗地讲,就是检测 data 内声明的数据。不仅可以监测简单数据,还可以监测对象或对象属性。

    Demo1:监测简单数据

    <input v-model="first" > <br>
    
    data(){
     return{
      first:'美女',
      }
     },
    watch:{
     first( newVal , oldVal ){
     console.log('newVal',newVal) // first 的最新值
     console.log('oldVal',oldVal) // first上一个值
     }
    },
    // 修改 first的值的时候,立马会打印最新值  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Demo2:监测对象

    监听对象的时候,需要使用深度监听

    <input v-model="per.name">
    
    data(){
     return{
      per:{
       name:'倩倩',
       age:'18'
       }
      }
     },
    watch:{
     per:{
      handler(oldVal,newVal){
       console.log('newVal',newVal)
       console.log('oldVal',oldVal)
      },
      deep:true,
     }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    修改 per.name 的时候,发现 newVal 和 oldVal 的值是一样的,是因为他们存储的指针指向的是同一个地方,所以深度监听虽然可以监听到对象的变化,但是无法监听到具体的是哪个属性发生变化了。

    Demo3:监听对象的单个属性

    // 方法1:直接引用对象的属性
    <input v-model="per.name">
    
    data(){
     return{
      per:{
       name:'倩倩',
       age:'18'
       }
      }
     },
    watch:{
     'per.name':function(newVal,oldVal){
       console.log('newVal->',newVal)
       console.log('oldVal->',oldVal)
      }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    也可以借助 computed 作为中间转换,如下:

    // 方法2:借助computed
    <input v-model="per.name">
    
    data(){
     return{
      per:{
       name:'倩倩',
       age:'18'
       }
      }
     },
    watch:{
     perName(){
      console.log('name改变了')
      }
    },
    computed:{
     perName:function(){
      return this.per.name
     }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Demo4:监听 props 组件传过来的值

    props:{
     mm:String
    },
    //不使用 immediate
    watch:{
     mm(newV,oldV){
       console.log('newV',newV)
       console.log('oldV',oldV)
     }
    }
    
    //使用 immediate
    watch:{
     mm:{
      immediate:true,
      handler(newV,oldV){
       console.log('newV',newV)
       console.log('oldV',oldV)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    不使用 immediate 时,第一次加载页面时,watch 监听的 mm 中的打印并没有执行。

    使用 immediate 时,第一次加载时也会打印结果:newV 11 oldV undefined。

    immediate 主要作用就是组件加载时,会立即触发回调函数。参考 前端vue面试题详细解答

    三、两者区别

    3.1、对于 computed

    • computed 监控的数据在 data 中没有声明
    • computed 不支持异步,当 computed 中有异步操作时,无法监听数据的变化
    • computed 具有缓存,页面重新渲染,值不变时,会直接返回之前的计算结果,不会重新计算
    • 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,一般使用 computed
    • computed 计算属性值是函数时,默认使用get方法。如果属性值是属性值时,属性有一个get和set方法,当数据发生变化时会调用set方法。
    computed:{
     //属性值为函数
     perName:function(){
      return this.per.name
     },
     //属性值为属性值
     full:{
      get(){  },
      set(val){  }
     }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.2、对于 watch

    • 监测的数据必须在 data 中声明或 props 中数据
    • 支持异步操作
    • 没有缓存,页面重新渲染时,值不改变时也会执行
    • 当一个属性值发生变化时,就需要执行相应的操作
    • 监听数据发生变化时,会触发其他操作,函数有两个参数:
    immediate :组件加载立即触发回调函数
    deep:深度监听,主要针对复杂数据,如监听对象时,添加深度监听,任意的属性值改变都会触发。
    注意:对象添加深度监听之后,输出的新旧值是一样的。
    
    • 1
    • 2
    • 3

    computed 页面重新渲染时,不会重复计算,而 watch 会重新计算,所以 computed 性能更高些。

    四、应用场景

    当需要进行数值计算,并且依赖于其它数据时,应该使用 computed ,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。

    当需要在数据变化时执行异步操作或开销较大的操作时,应该使用 watch,computed 不支持异步。如果需要限制执行操作的频率,可借助 computed 作为中间状态。

  • 相关阅读:
    前端面试八股文
    HDU-3549 Flow Problem 简单最大流
    《网络协议》04. 应用层(DNS & DHCP & HTTP)
    Day661.分析定位Java问题工具① -Java业务开发常见错误
    非稳压高压电源模块12SMV300 HV05200S-W2 HV12180S-2W直流转换器
    总结1008
    (C语言)P1002 [NOIP2002 普及组] 过河卒
    建模助手:Revit中捕捉点设置问题和楼层排序设置
    【LeetCode-简单题】69. x 的平方根
    JAVA面试题——CAS原理
  • 原文地址:https://blog.csdn.net/bb_xiaxia1998/article/details/127644813