vue中computed 和 watch 区别

computed:通过属性计算而得来的属性

使用场景:当一个值受多个属性影响的时候

  1. computed 是计算属性,也就是依赖某个值或者 props 通过计算得来得数据;
  2. 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化;
  3. computed 内部的函数在调用时不加();
  4. computed 的值是在 getter 执行之后进行缓存的,只有在它依赖的数据发生变化,会重新调用 getter 来计算;
  5. computed 是依赖 vm 中 data 的属性变化而变化的,也就是说,当 data 中的属性发生改变的时候,当前函数才会执行,data 中的属性没有改变的时候,当前数不会执行;
  6. computed 中的函数必须用 return 返回;
  7. 在 computed 中不要对 data 中的属性进行赋值操作。如果对 data 中的属性进行赋值操作了,就是 data 中的属性发生改变,从而触发 computed 中的函数,成死循环了;
  8. 当 computed 中的函数所依赖的属性没有发生改变,那么调用当前函数的时候会从缓存中读取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div>
<p>{{ reversedMessage }}</p>
</div>
</template>

<script>
export default {
name: 'test1',
data () {
return {
message: 'hello world',
number: 1
}
},
computed: {
// 字符串反转
reversedMessage () {
return this.message.split('').reverse().join('') + this.number
}
}
}
</script>

computed 中定义的每一个计算属性,都会被缓存起来,只有当计算属性里面依赖的一个或多个属性变化了,才会重新计算当前计算属性的值。上面的代码片段中,在 reversedMessage 中,它依赖了 message 和 number 这两个属性,一旦其中一个变化了,reversedMessage 会立刻重新计算输出新值。

watch:属性监听

使用场景:当一条数据的更改影响到多条数据的时候

  1. watch 是监听器,可以监听某一个数据,然后执行相应的操作;
  2. 不支持缓存,数据变直接会触发相应的操作;
  3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  4. 支持异步操作;
  5. watch 中的函数名称必须要和 data 中的属性名一致,因为 watch 是依赖 data 中的属性,当 data 中的属性发生改变的时候,watch 中的函数就会执行;
  6. watch 中的函数有两个参数,前者是 newVal,后者是 oldVal
  7. watch 中的函数是不需要调用的;
  8. watch 只会监听数据的值是否发生改变,而不会去监听数据的地址是否发生改变。也就是说,watch 想要监听引用类型数据的变化,需要进行深度监听。
    "obj.name"(){ }:如果 obj 的属性太多,这种方法的效率很低,
    obj:{ handler(newVal){ }, deep: true }:用 handler + deep 的方式进行深度监听;
  9. 特殊情况下,watch 无法监听到数组的变化,特殊情况就是说更改数组中的数据时,数组已经更改,但是视图没有更新。更改数组必须要用 splice()或者$set。
    this.arr.splice(0,1,100):修改arr中第0项开始的1个数据为100,
    this.$set(this.arr,0,100):修改 arr 第 0 项值为 100;
  10. immediate:true 页面首次加载的时候做一次监听
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<div>
<p>{{ this.number }}</p>
</div>
</template>

<script>
export default {
name: 'test1',
data () {
return {
number: 1
}
},
created () {
setTimeout(() => {
this.number = 100
}, 2000)
},
watch: {
number (newVal, oldVal) {
console.log('number has changed: ', newVal)
}
}
}
</script>

上面的代码中,我们在 watch 中监听了 number 属性,并且在实例创建后 2s 执行对 number 属性的值的更改。输出如下:

1
number has changed: 100

区别:

  1. 功能上:computed 是计算属性,watch 是监听一个值的变化,然后执行对应的回调。
  2. 是否调用缓存:computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而 watch 在每次监听的值发生变化的时候都会执行回调。
  3. 是否调用 return:computed 中的函数必须要用 return 返回,watch 中的函数不是必须要用 return。
  4. 使用场景:computed—-当一个属性受多个属性影响的时候,使用 computed——-购物车商品结算。watch—-当一条数据影响多条数据的时候,使用 watch——-搜索框。

总结:computed 和 watch 的使用场景并不一样,computed 的话是通过几个数据的变化,来影响一个数据,而 watch,则是可以一个数据的变化,去影响多个数据。

补充:computed 跟 methods 里面的方法的区别,computed 的话访问的时候会直接返回已缓存的结果,而不会像 methods 一样再次计算