一文搞懂Vue中computed和watch的区别

 更新时间:2022年11月18日 10:53:28   作者:风度翩翩的红金鱼  
这篇文章主要和大家详细介绍一下Vue中computed和watch的使用与区别,文中通过示例为大家进行了详细讲解,对Vue感兴趣的同学,可以学习一下

一、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('方法')
  return this.first + ' ' + this.second
 }
 }

运行结果为:

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

二、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的值的时候,立马会打印最新值

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

修改 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)
  }
},

也可以借助 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
 }
},

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

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

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

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

三、两者区别

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

3.2、对于 watch

  • 监测的数据必须在 data 中声明或 props 中数据
  • 支持异步操作
  • 没有缓存,页面重新渲染时,值不改变时也会执行
  • 当一个属性值发生变化时,就需要执行相应的操作
  • 监听数据发生变化时,会触发其他操作,函数有两个参数:

immediate :组件加载立即触发回调函数

deep:深度监听,主要针对复杂数据,如监听对象时,添加深度监听,任意的属性值改变都会触发。

注意:对象添加深度监听之后,输出的新旧值是一样的。

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

四、应用场景

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

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

到此这篇关于一文搞懂Vue中computed和watch的区别的文章就介绍到这了,更多相关Vue computed watch内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 利用Vue实现移动端图片轮播组件的方法实例

    利用Vue实现移动端图片轮播组件的方法实例

    轮播图是前端很常用的一个网页特效,几乎所有的网站或多或少都会用到这个特效。下面这篇文章主要给大家介绍了关于利用Vue实现移动端图片轮播组件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2017-08-08
  • vue-router 路由传参问题(路由传参方式)

    vue-router 路由传参问题(路由传参方式)

    路由传参主要有两种方式一种是路径传参一种是参数传递,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-11-11
  • Vue3中自定义事件总线的实现代码

    Vue3中自定义事件总线的实现代码

    随着 Vue 3 的发布,一些在 Vue 2 中常用的通信方式在 Vue 3 中可能不再适用或有所变化,为了应对这种变化,我们可以选择在 Vue 3 应用中实现自定义的“事件总线”机制,所以本文给大家介绍了Vue3中如何自定义消息总线,需要的朋友可以参考下
    2024-05-05
  • 使用 vue.js 构建大型单页应用

    使用 vue.js 构建大型单页应用

    本文给大家详细介绍了如何使用使用 vue.js脚手架工具vue-cli构建大型单页应用的方法,非常的实用,有需要的小伙伴可以参考下
    2018-02-02
  • 详细聊聊Vue生命周期的那些事

    详细聊聊Vue生命周期的那些事

    这篇文章主要给大家介绍了关于Vue生命周期的那些事,在使用vue开发过程中经常会接触到生命周期的问题,但对于每个钩子函数都做了什么,应用场景比较模糊,希望通过这次梳理让自己清楚一些,需要的朋友可以参考下
    2021-09-09
  • Vuex的各个模块封装的实现

    Vuex的各个模块封装的实现

    这篇文章主要介绍了Vuex的各个模块封装的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Vue按需加载的具体实现

    Vue按需加载的具体实现

    本篇文章主要介绍了Vue按需加载的具体实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Vue通过axios发送ajax请求基础演示

    Vue通过axios发送ajax请求基础演示

    这篇文章主要介绍了Vue通过axios发送ajax请求基础演示,包括了axios发送简单get请求,axios get传参,axios发送post请求等基础代码演示需要的朋友可以参考下
    2023-02-02
  • 详解vue-router基本使用

    详解vue-router基本使用

    本篇文章主要介绍了详解vue-router基本使用,详细的介绍了vue-router的概念和用法,有兴趣的可以了解一下。
    2017-04-04
  • Vue3使用Suspense优雅地处理异步组件加载的示例代码

    Vue3使用Suspense优雅地处理异步组件加载的示例代码

    Vue3是Vue.js的最新版本,它带来了许多令人兴奋的新特性和改进,其中一个重要的特性是Suspense,它为我们提供了一种优雅地处理异步组件加载和错误处理的方式,本文给大家介绍了Vue3使用Suspense优雅地处理异步组件加载的示例,需要的朋友可以参考下
    2024-01-01

最新评论