Zonebit

个人的奋斗还是历史的进程?

View the Project on GitHub

18 August 2024

Computed原理

by

computed原理

前置知识

观察者模式,属性描述符,访问器属性

响应式

初始化data

observe(data) => new Observer() => defineReactive(data, key)

defineReactive方法展开

在getter中dep.depend

在setter中dep.notify => sub.update

在初始化计算属性的时候,会对每个计算属性构造一个Watcher实例,这个实例的get方法

首先会执行pushTarget(this),将当前的Watcher实例设置为全局唯一的Watcher实例(通过Dep.target引用)

然后,会通过执行我们定义的计算属性的方法体,这个时候就会依次访问到计算属性依赖的各个响应式属性

这个时候,这些属性的get方法就会执行dep.depend(),depend方法实际执行了Dep.target.addDeps(this),addDeps方法通过dep.addSub(this)将全局唯一的Watcher实例跟dep关联起来

这样,每个属性的dep都关联到了全局Watcher——也即计算属性收集到了所有的依赖项

这些依赖项的setter方法中,执行了dep.notify(),对所有sub(Watcher)执行了update方法,update方法将Watcher实例的dirty属性置为true

当访问计算属性时,使用的是computedGetter方法(这个方法跟Watcher的get方法不是同一个方法,注意区分),这个方法会获取到计算属性对应的Watcher实例,判断dirty值为true时就执行watcher.evaluate(),最终返回watcher.value

后记

观察者模式实现的逻辑是反常识的——这也是我一直以来无法理解它的原因之一

一些疑问点

watcher为什么有run和evaluate两个方法

解析三类watcher——computed,渲染,watch

vue3与vue2中watcher类的异同

定时器

tags: