1.computed1.1 定义

是一个计算属性,类似于过滤器,对绑定到view的数据进行处理

1.2 get用法

data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName ' ' this.lastName } }

1.3 get和set用法

data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName:{ get(){//回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值 return this.firstName ' ' this.lastName }, set(val){//监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据 //val就是fullName的最新属性值 console.log(val) const names = val.split(' '); console.log(names) this.firstName = names[0]; this.lastName = names[1]; } } }

computed的缓存功能

首先,我们要明白缓存究竟有什么用?相比大家都知道HTTP缓存,其核心作用就是对一些服务端未更新的资源进行复用,避免一些无谓的请求,优化了用户的体验

对于computed也是一样的:

在Vue实例化的时候,computed定义computedTest方法会做一次计算,返回一个值

在随后的代码编写中,只要computedTest方法依赖的message数据不发生改变,computedTest方法是不会重新计算的

2. watch2.1 定义

watch是一个观察的动作

2.2 示例

data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val ' ' this.lastName }, lastName: function (val) { this.fullName = this.firstName ' ' val } }

上面是监听firstName和lastName的变化,但是仅限简单数据类型

2.2 监听简单数据类型

data(){ return{ 'first':2 } }, watch:{ first(){ console.log(this.first) } },

2.3 监听复杂数据类型

1.监听复杂数据类型需用深度监听

data(){ return{ 'first':{ second:0 } } }, watch:{ secondChange:{ handler(oldVal,newVal){ console.log(oldVal) console.log(newVal) }, deep:true } },

2.console.log打印的结果,发现oldVal和newVal值是一样的,所以深度监听虽然可以监听到对象的变化,但是无法监听到具体对象里面那个属性的变化

3.oldVal和newVal值一样的原因是它们索引同一个对象/数组。Vue 不会保留修改之前值的副本vm.$watch的深度监听

vueresource用法(一文搞懂vue中computedwatchmethon等区别)(1)

4.深度监听对应的函数名必须为handler,否则无效果,因为watcher里面对应的是对handler的调用

2.4 监听对象单个属性

方法一:可以直接对用对象.属性的方法拿到属性

data(){ return{ 'first':{ second:0 } } }, watch:{ first.second:function(newVal,oldVal){ console.log(newVal,oldVal); } },

方法二:watch如果想要监听对象的单个属性的变化,必须用computed作为中间件转化,因为computed可以取到对应的属性值

data(){ return{ 'first':{ second:0 } } }, computed:{ secondChange(){ return this.first.second } }, watch:{ secondChange(){ console.log('second属性值变化了') } },

关键的watcher.js
  • get 收集依赖
  • udpate 更新dirty为true,从而可以重新evaluate
  • evaluate 重新获得computed属性的值
  • depend 通知dep收集依赖
  • adddep watcher订阅依赖
关键的dep.js
  • addSub:添加订阅
  • depend: 添加依赖
  • notify:通知更新
3、 computed和watch的区别
  1. 要计算的属性会随着其依赖的data中属性变化而变化,只要依赖的属性改变,就会执行computed,若无改变,则直接从缓存中取值
  2. 支持缓存,只有依赖数据发生改变,才会重新进行计算
  3. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
  4. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
  5. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
  6. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
3.1 computed特性
  1. 不支持缓存,数据变,直接会触发相应的操作;
  2. watch支持异步;
  3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  4. 当一个属性发生变化时,需要执行对应的操作;一对多;
  5. 监听的是这个属性自身的变化,且不会操作缓存
  6. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
3.2 watch特性

1.是观察的动作,2.应用:监听props,$emit或本组件的值执行异步操作3.无缓存性,页面重新渲染时值不变化也会执行

3 props传值3.1 常见错误1

传入的值想作为局部变量来使用,直接使用会

props:['listShop'], data(){ return{} }, created(){ this.listShop=30 }

报错

vueresource用法(一文搞懂vue中computedwatchmethon等区别)(2)

这个错误是说的避免直接修改父组件传入的值,因为会改变父组件的值,贴上官网介绍

3.2 解决方案1

简单数据类型解决方案:所以可以在data中重新定义一个变量,改变指向,但是也只是针对简单数据类型,因为复杂数据类型栈存贮的是指针,

props:['listShop'], data(){ return{ listShopChild:this.listShop } }, created(){ this.listShopChild=30 }

这样就可以愉快的更改传入的简单数据类型的数据啦!不会有任何报错,也不会影响父组件!

4、计算属性vs方法
  1. 调用方式不同。computed直接以对象属性方式调用,不需要加括号,而methods必须要函数执行才可以得到结果。
  2. 绑定方式不同。methods与compute纯get方式都是单向绑定,不可以更改输入框中的值。compute的get与set方式是真正的双向绑定。
  3. 是否存在缓存。methods没有缓存,调用相同的值计算还是会重新计算。competed有缓存,在值不变的情况下不会再次计算,而是直接使用缓存中的值。

在官方文档中,强调了computed区别于method最重要的两点

  1. computed是属性访问,而methods是函数调用
  2. computed带有缓存功能,而methods不是

Vue中,copmuted和methods写法上有些相似,但是还是有一些不同点。

1.计算属性是有一个返回值的,且必须有,返回值是一个差值表达式,而函数是不需要的,有没有返回值或者返回值是什么类型没有限制。(返回值方面)

2.用法上,在某些情况下是可以用方法代替计算属性的,比如某个不需要监听的值,而当值会变化并且视图需要随着值得变化去更新的话就不能用方法。(视图更新方面)

3.在写上也有些不同方法必须后面带()并且可以传参,而计算属性是不用调用的,直接用且不能传参。(写法方面)

4.计算属性是有缓存的。(性能方面)

5、计算属性 vs 侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。

计算属性对比侦听属性(watch)来说,前者更像是一个方法,后者更像是一个命令。性能方面计算属性会更好一点,例如:

vueresource用法(一文搞懂vue中computedwatchmethon等区别)(3)

conputed看起来更加好一点,但是,watch就毫无用处了吗,官方给出了解释

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

计算属性的用法

目前版本的Vue中是不支持对象的双向绑定的,举个例子:

vueresource用法(一文搞懂vue中computedwatchmethon等区别)(4)

上述代码中直接引用发生变化是不会更新视图的,而computed和watch是可以的,具体原因大家可以去了解一下深拷贝和浅拷贝,值传递和引用传递。这个例子告诉我们对对象的监听是有两种方法的,并且computed的性能会更好一点。

当然,Vue3.0事已经解决了这个问题,可以不做处理了

,