watch和computed的区别以及选择?

本文对比讲解了Vue3中Computed和Watch的区别,包括定义、使用场景、缓存、异步操作、选择依据以及在不同情况下的应用。着重介绍了如何利用Computed简化表达式和其缓存优势,以及何时使用Watch进行状态监听和异步操作。

目录

思路分析

回答范例

可能追问

1. Computed介绍

1.1、get 和 set 用法

1.2、计算属性缓存

二、watch介绍

监测简单数据

监测对象

监听对象的单个属性

借助computed

监听 props 组件传过来的值

对于 computed

对于 watch

应用场景


两个重要API,反应应聘者熟练程度。

思路分析

  1. 先看两者定义,列举使用上的差异
  2. 列举使用场景上的差异,如何选择
  3. 使用细节、注意事项
  4. vue3变化

回答范例

  1. 计算属性可以从组件数据派生出新数据,最常见的使用方式是设置一个函数,返回计算之后的结果,computed和methods的差异是它具备缓存性,如果依赖项不变时不会重新计算。侦听器可以侦测某个响应式数据的变化并执行副作用,常见用法是传递一个函数,执行副作用,watch没有返回值,但可以执行异步操作等复杂逻辑。
  2. 计算属性常用场景是简化行内模板中的复杂表达式,模板中出现太多逻辑会是模板变得臃肿不易维护。侦听器常用场景是状态变化之后做一些额外的DOM操作或者异步操作。选择采用何用方案时首先看是否需要派生出新值,基本能用计算属性实现的方式首选计算属性。
  3. 使用过程中有一些细节,比如计算属性也是可以传递对象,成为既可读又可写的计算属性。watch可以传递对象,设置deep、immediate等选项。
  4. vue3中watch选项发生了一些变化,例如不再能侦测一个点操作符之外的字符串形式的表达式; reactivity API中新出现了watch、watchEffect可以完全替代目前的watch选项,且功能更加强大。

可能追问

  1. watch会不会立即执行 ?
  2. watch 和 watchEffect有什么差异 ?( vue3中的watchEffect )

1、不会立即执行,在监听到数据变化了才会改变,

指定 immediate: true 将立即以表达式的当前值触发回调,即在 wacth 中声明了 firstName 之后就会立即执行里面的 handler 方法,如果为 false 就跟原来的效果一样,不会在绑定的时候就执行

1. Computed介绍

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

 //基础使用
  {{msg}}
  <input v-model="name" />   
  //计算属性 
  computed:{
    msg:function(){
      return this.name
    }
  }

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

注意:msg 不可在 data 中定义,否则会报错(计算属性不可在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]
       }
   }
}

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
      }
  }

一个页面内,数据有可能多次使用,我们把 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('method')
      return this.first + ' ' + this.second
   }
  }

运行结果为:

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

二、watch介绍

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

监测简单数据

 <input v-model="first" > <br>  
  data(){
     return{
      first:'美女',
    }
  },
 watch:{
   first( newVal , oldVal ){
     console.log('newVal',newVal) // first 的最新值
     console.log('oldVal',oldVal) // first上一个值
    }
 }
 // 修改 first的值的时候,立马会打印最新值  

监测对象

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

 <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,
   }
  },

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

监听对象的单个属性

  // 方法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)
     }
  }

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

借助computed

 <input v-model="per.name">

 data(){
   return{
      per:{
         name:'倩倩',
         age:'18'
      }
    }
  },
  watch:{
   perName(){
     console.log('name改变了')
    }
 },
 computed:{
   perName:function(){
    return this.per.name
    }
 }

监听 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)
   }
 }

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

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

immediate 主要作用就是组件加载时,会立即触发回调函数。

对于 computed

  • computed 监控的数据在 data 中没有(不用)声明

  • computed 不支持异步,当 computed 中有异步操作时,无法监听数据的变化

  • computed 具有缓存,页面重新渲染,值不变时,会直接返回之前的计算结果,不会重新计算

  • 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,一般使用 - ------computed

  • computed 计算属性值是函数时,默认使用get方法。如果属性是完整写法时,属性有一个get和set方法,当数据发生变化时会调用set方法

      computed:{
       //属性值为函数
      perName:function(){
        return this.per.name
     },
      //完整写法
     full:{
      get(){  },
       set(val){  }
     }
    },
    

对于 watch

  • 监测的数据必须在 data 中声明或 props 中数据

  • 支持异步操作

  • 没有缓存,页面重新渲染时,值不改变时也会执行

  • 当一个属性值发生变化时,就需要执行相应的操作

  • 监听数据发生变化时,会触发其他操作,函数有两个参数:

      immediate :组件加载立即触发回调函数
      deep:深度监听,主要针对复杂数据,如监听对象时,添加深度监听,任意的 
      属性值改变都会触发。
      注意:对象添加深度监听之后,输出的新旧值是一样的。
    

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

应用场景

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

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值