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

180 阅读3分钟

computed:

  1. 它是计算属性。主要用于值的计算并一般会返回一个值。所以它更多⽤于计算值的场景
  2. 它具有缓存性。当访问它来获取值时,它的 getter 函数所计算出来的值会进行缓存
  3. 只有当它依赖的属性值发生了改变,那下⼀次再访问时才会重新调⽤ getter 函数来计算
  4. 它适⽤于计算⽐较消耗性能的计算场景
  5. 必须要有一个返回值

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

javascript
复制代码
//基础使用
{{msg}}
<input v-model="name" /> 

 //计算属性 
computed:{
 msg(){
  return this.name
 }
}

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

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

1.1、get 和 set 用法

kotlin
复制代码
<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、计算属性缓存

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

kotlin
复制代码
<div> {{ full() }} </div>

data(){
 return{
  first:'美女',
  second:'姐姐'
 }
},
methods:{
 full(){
 return this.first + ' ' + this.second
 }
},

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

javascript
复制代码
<div>
  computed计算值:
  {{full}} {{full}} {{full}} {{full}}
</div>

<div>
  methods计算值:  {{fullt}} {{fullt}} {{fullt}} {{fullt}}
</div>

data(){
 return{
  first:'美女',
  second:'姐姐'
 }
},
computed:{
 full(){
  console.log('computed')
  return this.first + ' ' + this.second
 }
},
methods:{
 fullt(){
  console.log('方法')
  return this.first + ' ' + this.second
 }
 }

运行结果为:

在这里插入图片描述

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

watch

  1. 它更多的是起到 “观察” 的作⽤,类似于对数据进行变化的监听并执行回调。 主要⽤于观察 props 或 本组件data的值,当这些值发生变化时,执⾏处理操作
  2. 不一定要返回某个值

语法:

  words: '苹果',
  obj: {
    words: '苹果'
  }
},

watch: {
  // 该方法会在数据变化时,触发执行
  数据属性名 (newValue, oldValue) {
    一些业务逻辑 或 异步操作。 
  },
  '对象.属性名' (newValue, oldValue) {
    一些业务逻辑 或 异步操作。 
  }
}

额外配置项:

1.  deep:true 对复杂类型进行深度监听
2.  immdiate:true 初始化 立刻执行一次```

data: {
  obj: {
    words: '苹果',
    lang: 'italy'
  },
},

watch: {// watch 完整写法
  对象: {
    deep: true, // 深度监视
    immdiate:true,//立即执行handler函数
    handler (newValue) {
      console.log(newValue)
    }
  }
}

使用场景:

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

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