全面分析 Vue 的 computed 和 watch 的区别

2021-11-18  本文已影响0人  元宇宙编程
一、computed介绍

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

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

在输入框中,改变 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]
       }
   }
}

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 主要作用就是组件加载时,会立即触发回调函数。

3.1、对于 computed
3.2、对于 watch

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

四、应用场景

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

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

上一篇 下一篇

猜你喜欢

热点阅读