【大白话】vue2之Watcher

475 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

介绍

observe、dep、watcher三巨头组成vue2数据响应式,其中observe是提供收集触发依赖时机,dep负责收集触发依赖,而watcher是对依赖的抽象,它隔离了数据状态反应。

👆🏻以上是非白话,下面👇我用一个碟子去打比喻

它就是个碟子

Watcher是一个类,里面有两个重要的参数:expression和cb。这两个参数vue项目中也是日常使用到,例如$watchoptions中的watch

// $watch内部会new一个Watcher
this.$watch('expression', cd)
{
    expression: cd
}

Watcher实例就像一个碟子,它只是一个载体,用来装各类食物。显而易见,食物才是我们需要关注的点

image.png

食物对应着Watcher的cd参数,cd是对于数据状态变化处理的回调函数,正如各种食材有无尽的配合,所以vue直接把这部分抽离成cd让开发者进行自定义。而食材则是expression,代码中我们监听的数据,通过回调函数进行不同状态处理

Watcher的身影

除了上面说的两种watch会实例出watcher,计算属性和render的时候也会有一个对应的watcher

计算属性

computed有两个特性:惰性&缓存,惰性是指初始化的时候不会先触发依赖收集,只有当真正使用到才会收集依赖。但watcher初始化默认情况下会先触发expression来收集依赖,为了阻止这个情况,计算属性new watcher的时候会传入lazy为false,这样就可以防止初始化依赖收集

还有就是缓存,只有当计算属性中响应式数据改变才会触发其get函数,由watcher的dirty属性来维护这个缓存状态

render

为什么修改响应式数据后,模板会重新渲染呢?这是因为有一个对应render watcher,每个响应式数据都会收集这个依赖,所以修改响应式任意数据时都会重新走模板渲染函数