• watch和computed的区别以及选择?


    目录

    思路分析

    回答范例

    可能追问

    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 里面定义,页面上可直接使用。

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

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

    注意:msg 不可在 data 中定义,否则会报错(计算属性不可在data中定义,会报错)

    1.1、get 和 set 用法

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

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

    1.2、计算属性缓存

    计算属性是基于它们的依赖项的值结果进行缓存的,只要依赖的变量不变, 都直接从缓存取结果

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

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

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

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

    运行结果为:

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

    二、watch介绍

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

    监测简单数据

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

    监测对象

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

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

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

    监听对象的单个属性

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

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

    借助computed

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

    监听 props 组件传过来的值

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

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

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

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

    对于 computed

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

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

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

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

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

      1. computed:{
      2. //属性值为函数
      3. perName:function(){
      4. return this.per.name
      5. },
      6. //完整写法
      7. full:{
      8. get(){ },
      9. set(val){ }
      10. }
      11. },

    对于 watch

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

    • 支持异步操作

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

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

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

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

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

    应用场景

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

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

  • 相关阅读:
    目标检测工具箱MMDetection安装及使用示例
    CMS与FullGC
    【物联网】NB-IoT
    SpringCloud 08 Feign 负载均衡和服务熔断
    PCB设计时如何选择合适的叠层方案
    wpf复制xaml及其cs窗体到其他项目 添加现有项,选 .xaml.cs,点添加即可。VS2022
    企业门户的必备选择,WorkPlus的定制化解决方案
    C语言函数调用的过程图解深入剖析
    微服务12:系统服务熔断、限流
    【Java项目实战】牛客网论坛项目1 - Spring入门与初识SpringMVC
  • 原文地址:https://blog.csdn.net/csdssdn/article/details/125503352