Vue中computed和watch的区别

computed和watch都能实现对数据的监听,但是二者还是存在区别:

  • 功能上:computed是计算属性,watch用来监听一个值的变化
  • computed有缓存,data中的数据不发生变化,不会重新计算;而watch每次监听的值发生变化都会执行回调
  • computed默认首次加载就开始监听,watch默认第一次加载不进行监听(设置属性immediate:true会开启默认第一次加载就开始监听)
  • computed属性值是一个函数,那么默认会走get方法,必须要有return返回值,watch不必有return返回值
  • watch支持异步
  • 选择computed还是watch? 官网说:当需要数据变化时执行异步或者开销较大的操作时,watch方式是最有用的。所以watch支持异步

总结:

watch和computed都是以Vue的依赖追踪机制为基础的,当某一个依赖型数据发生变化的时候,所有依赖这个数据的相关数据会自动发生变化,即自动调用相关的函数,来实现数据的变动。

(依赖型数据:简单理解即放在 data 等对象下的实例数据)

当依赖的值变化时,在watch中,是可以做一些复杂的操作的,而computed中的依赖,仅仅是一个值依赖于另一个值,是值上的依赖。

computed是如何实现缓存的?

围绕一个例子,讲解computed初始化及更新时的流程,来看看计算属性是怎么实现缓存的以及依赖是怎么被收集的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div id="app">
<span @click="change">{{sum}}</span>
</div>
<script src="./vue2.6.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
count: 1,
}
},
methods: {
change() {
this.count = 2
},
},
computed: {
sum() {
return this.count + 1
},
},
})
</script>

1.初始化computed

vue初始化时先执行init方法,里面的initState会进行计算属性的初始化

1
if (opts.computed) {initComputed(vm, opts.computed);}

下面是initComputed的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
var watchers = vm._computedWatchers = Object.create(null); 
// 依次为每个 computed 属性定义一个计算watcher
for (const key in computed) {
const userDef = computed[key]
watchers[key] = new Watcher(
vm, // 实例
getter, // 用户传入的求值函数 sum
noop, // 回调函数 可以先忽视
{ lazy: true } // 声明 lazy 属性 标记 computed watcher
)
// 用户在调用 this.sum 的时候,会发生的事情
defineComputed(vm, key, userDef)
}
文章作者: qinwei
文章链接: https://qw-null.github.io/2022/08/09/Vue中computed和watch的区别/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 QW's Blog