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 相关文章推荐
使用js声明数组,对象在jsp页面中(获得ajax得到json数据)
Nov 05 Javascript
js确认删除对话框适用于a标签及submit
Jul 10 Javascript
jQuery实现仿美橙互联两级导航菜单的方法
Mar 09 Javascript
深入理解Vue transition源码分析
Jul 30 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
Jul 03 Javascript
详解vue-cli下ESlint 配置说明
Sep 03 Javascript
JS根据json数组多个字段排序及json数组常用操作
Jun 06 Javascript
弱类型语言javascript中 a,b 的运算实例小结
Aug 07 Javascript
vue项目打包之开发环境和部署环境的实现
Apr 23 Javascript
Vue 中获取当前时间并实时刷新的实现代码
May 12 Javascript
封装 axios+promise通用请求函数操作
Aug 11 Javascript
vant 中van-list的用法说明
Nov 11 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
php基础知识:控制结构
2006/12/13 PHP
php使用mysqli向数据库添加数据的方法
2015/03/20 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
PHP编程计算文件或数组中单词出现频率的方法
2017/05/22 PHP
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
可恶的ie8提示缺少id未定义
2014/03/20 Javascript
js传值后台中文出现乱码的解决方法
2016/06/30 Javascript
AngularJS表达式讲解及示例代码
2016/08/16 Javascript
jquery封装插件时匿名函数形参和实参的写法解释
2017/02/14 Javascript
vue如何实现observer和watcher源码解析
2017/03/09 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
详解a标签添加onclick事件的几种方式
2019/03/29 Javascript
详解vue页面首次加载缓慢原因及解决方案
2019/11/06 Javascript
JS控制下拉列表左右选择实例代码
2020/05/08 Javascript
vue使用canvas实现移动端手写签名
2020/09/22 Javascript
利用JS判断元素是否为数组的方法示例
2021/01/08 Javascript
为python设置socket代理的方法
2015/01/14 Python
python 创建弹出式菜单的实现代码
2017/07/11 Python
python机器学习理论与实战(四)逻辑回归
2018/01/19 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
python斐波那契数列的计算方法
2018/09/27 Python
python 判断三个数字中的最大值实例代码
2019/07/24 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
2019/08/09 Python
Python学习笔记之For循环用法详解
2019/08/14 Python
wxPython色环电阻计算器
2019/11/18 Python
python中导入 train_test_split提示错误的解决
2020/06/19 Python
python matplotlib工具栏源码探析二之添加、删除内置工具项的案例
2021/02/25 Python
CSS3 border-image详解、应用及jQuery插件
2011/08/29 HTML / CSS
预备党员2014全国两会学习心得体会
2014/03/10 职场文书
超市开业庆典策划方案
2014/05/14 职场文书
主题班会演讲稿
2014/05/22 职场文书
在校生证明
2015/06/17 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
天谕手游15杯全调酒配方和调酒券的获得方式
2022/04/06 其他游戏
详解Mysq MVCC多版本的并发控制
2022/04/29 MySQL