vue中watch和computed的区别与使用方法


Posted in Javascript onAugust 23, 2020

computed 计算属性说明:

computed 是基于响应性依赖来进行缓存的。只有依赖数据发生改变,才会重新进行计算(当触发重新渲染,若依赖数据没有改变,则 computed 不会重新计算)。若没改变,计算属性会立即返回之前缓存的计算结果。

不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化的值。

computed 中的成员可以只定义一个函数作为只读属性, 也可以定义成 get/set 变成可读写属性

如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用 computed。

下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
 now: function () {
 return Date.now()
 }
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

watch 监听属性说明:

不支持缓存,数据变或者触发重新渲染时,直接会触发相应的操作。

watch 支持异步

当一个属性发生变化时,需要执行对应的操作;一对多时,一般用 watch。

监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数,immediate:组件加载立即触发回调函数执行,deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep 无法监听到数组的变动和对象的新增,参考 vue 数组变异,只有以响应式的方式触发才会被监听到。

watch 和 computed 的区别是:

相同点:

两者都是观察页面数据变化的。

不同点:

  • computed 只有当依赖的数据变化时才会计算, 会缓存数据。
  • watch 每次都需要执行函数。watch 更适用于数据变化时的异步操作。

使用 参考官方文档

computed 使用

类型:{ [key: string]: Function | { get: Function, set: Function } }

详细:

计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。

注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

computed: {
 aDouble: vm => vm.a * 2
}

计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的。

示例:

var vm = new Vue({
 data: { a: 1 },
 computed: {
  // 仅读取
  aDouble: function () {
   return this.a * 2
  },
  // 读取和设置
  aPlus: {
   get: function () {
    return this.a + 1
   },
   set: function (v) {
    this.a = v - 1
   },
  },
 },
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4

watch 使用 与 解释

类型:{ [key: string]: string | Function | Object | Array }

详细:

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property。

示例:

var vm = new Vue({
 data: {
  a: 1,
  b: 2,
  c: 3,
  d: 4,
  e: {
   f: {
    g: 5,
   },
  },
 },
 watch: {
  a: function (val, oldVal) {
   console.log('new: %s, old: %s', val, oldVal)
  },
  // 方法名
  b: 'someMethod',
  // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
  c: {
   handler: function (val, oldVal) {
    ;/_ ... _/
   }, // or handler:'方法名'
   deep: true,
  },
  // 该回调将会在侦听开始之后被立即调用
  d: {
   handler: 'someMethod', // or handler: function(val, oldVal){}
   immediate: true,
  },
  // 你可以传入回调数组,它们会被逐一调用
  e: [
   'handle1',
   function handle2(val, oldVal) {
    /* ... */
   },
   {
    handler: function handle3(val, oldVal) {
     /* ... */
    },
    /* ... */
   },
  ],
  // watch vm.e.f's value: {g: 5}
  'e.f': function (val, oldVal) {
   ;/_ ... _/
  },
 },
})
vm.a = 2 // => new: 2, old: 1

说明: 对应上方的 a~e

a: 监听一个属性,需要使用前后变化值时使用

b: 监听一个属性,不会使用到改变前后的值,只为了执行一些方法,可以使用字符串代替 字符串代表方法名

c: 在监听一个对象时,当对象内部的属性被改变时,无法触发 watch,设置 deep 为 true 后,无论嵌套多深,只要属性值被改变都会触发监听。但这种方式开销会较大,监听器会一层一层往下找,为每个属性添加监听器。

如果我们只是监听对象的某个属性改变时,可以这样做:

watch:{
  'user.name':{
   handler: 'method'
  }

 }

d: watch 是在监听属性改变时才会触发,组件创建时可能不会执行,因此我们可以设置 immediate: true,就会让在组件创建后 watch 能够立即执行一次。就不用在 create 的时候去修改属性啦。

handelr: 触发监听执行的方法(需要用到改变前后的值时,可换成函数)

immediate: 监听开始之后被立即调用

e: 监听一个属性,执行多个函数包括回调等

注意,不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

总结

到此这篇关于vue中watch和computed的区别与使用方法的文章就介绍到这了,更多相关vue watch和computed的区别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Javascript 获取链接(url)参数的方法[正则与截取字符串]
Feb 09 Javascript
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
Jun 19 Javascript
基于jquery实现的一个选择中国大学的弹框 (数据、步骤、代码)
Jul 26 Javascript
js日期时间补零的小例子
Mar 05 Javascript
js 控制图片大小核心讲解
Oct 09 Javascript
js中的布尔运算符使用介绍
Nov 20 Javascript
javascript内置对象arguments详解
Mar 16 Javascript
使用js画图之画切线
Jan 12 Javascript
深入浅析javascript立即执行函数
Oct 23 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
Jan 26 Javascript
说说如何在Vue.js中实现数字输入组件的方法
Jan 08 Javascript
如何让微信小程序页面之间的通信不再变困难
Jun 03 Javascript
vue动态设置页面title的方法实例
Aug 23 #Javascript
Vue管理系统前端之组件拆分封装详解
Aug 23 #Javascript
Vue中keep-alive组件的深入理解
Aug 23 #Javascript
google广告之另类js调用实现代码
Aug 22 #Javascript
JS typeof fn === 'function' && fn()详解
Aug 22 #Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
Aug 22 #Javascript
JavaScript中的函数式编程详解
Aug 22 #Javascript
You might like
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
《魔兽争霸3:重制版》翻车了?你想要的我们都没有
2019/11/07 魔兽争霸
PHP中魔术变量__METHOD__与__FUNCTION__的区别
2014/09/29 PHP
PHP IDE PHPStorm配置支持友好Laravel代码提示方法
2015/05/12 PHP
php基于curl实现随机ip地址抓取内容的方法
2016/10/11 PHP
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
jQuery中animate动画第二次点击事件没反应
2015/05/07 Javascript
深入解析JavaScript中的数字对象与字符串对象
2015/10/21 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
微信小程序  Mustache语法详细介绍
2016/10/27 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
Javascript实现跨域后台设置拦截的方法详解
2017/08/04 Javascript
关于meta viewport中target-densitydpi属性详解(推荐)
2017/08/18 Javascript
vue+springmvc导出excel数据的实现代码
2018/06/27 Javascript
Vue触发隐藏input file的方法实例详解
2019/08/14 Javascript
java实现单链表增删改查的实例代码详解
2019/08/30 Javascript
Vue+Spring Boot简单用户登录(附Demo)
2020/11/12 Javascript
详解vite2.0配置学习(typescript版本)
2021/02/25 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
[01:05:00]2018国际邀请赛 表演赛 Pain vs OpenAI
2018/08/24 DOTA
Python使用cx_Oracle模块操作Oracle数据库详解
2018/05/07 Python
python实现多人聊天室
2020/03/31 Python
python实现AES加密解密
2019/03/28 Python
python实现爬取百度图片的方法示例
2019/07/06 Python
Django用户身份验证完成示例代码
2020/04/03 Python
彻底解决Python包下载慢问题
2020/11/15 Python
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
MIRTA官网:手工包,100%意大利制造
2020/02/11 全球购物
优秀经理事迹材料
2014/02/01 职场文书
深入开展党的群众路线教育实践活动方案
2014/02/04 职场文书
家长会演讲稿
2014/04/26 职场文书
办理房产证委托书
2014/09/18 职场文书
集结号观后感
2015/06/08 职场文书
学习十八大的感悟
2015/08/11 职场文书
完美处理python与anaconda环境变量的冲突问题
2021/04/07 Python