refactor(reactivity): 重构响应式系统依赖收集机制
- 将依赖管理逻辑分离到独立的dep模块 - 创建Dep类型定义和createDep工厂函数 - 修改KeyToDepMap类型以使用Dep集合替代单个ReactiveEffect - 添加trackEffects函数用于统一跟踪依赖 - 实现triggerEffects函数用于批量触发依赖 - 增加triggerEffect函数用于触发单个依赖 - 在effect运行时添加注释说明首次getter触发 - 添加HTML示例文件验证多依赖收集功能
This commit is contained in:
7
packages/reactivity/src/dep.ts
Normal file
7
packages/reactivity/src/dep.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { ReactiveEffect } from './effect'
|
||||
|
||||
export type Dep = Set<ReactiveEffect>
|
||||
export const createDep = (effects?: ReactiveEffect[]): Dep => {
|
||||
const dep = new Set<ReactiveEffect>(effects) as Dep
|
||||
return dep
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
type KeyToDepMap = Map<any, ReactiveEffect>
|
||||
import { createDep, Dep } from './dep'
|
||||
import { isArray } from '@vue/shared'
|
||||
|
||||
type KeyToDepMap = Map<any, Dep>
|
||||
/**
|
||||
* 收集所有依赖的WeakMap实例
|
||||
* key: 响应性对象
|
||||
@@ -18,8 +21,9 @@ export let activeEffect: ReactiveEffect | undefined
|
||||
export class ReactiveEffect<T = any> {
|
||||
constructor(public fn: () => T) {}
|
||||
run() {
|
||||
//当前被激活的effect实例
|
||||
activeEffect = this
|
||||
return this.fn()
|
||||
return this.fn() //完成第一次getter行为的触发
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +40,20 @@ export function track(target: object, key: unknown) {
|
||||
if (!depsMap) {
|
||||
targetMap.set(target, (depsMap = new Map()))
|
||||
}
|
||||
//为指定map, 指定key, 设置回调函数
|
||||
depsMap.set(key, activeEffect)
|
||||
console.log(targetMap)
|
||||
|
||||
let dep = depsMap.get(key)
|
||||
if (!dep) {
|
||||
depsMap.set(key, (dep = createDep()))
|
||||
}
|
||||
|
||||
trackEffects(dep)
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用dep依次跟踪指定key的所有effect
|
||||
*/
|
||||
export function trackEffects(dep: Dep) {
|
||||
dep.add(activeEffect!)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,10 +68,29 @@ export function trigger(target: object, key: unknown, newValue: unknown) {
|
||||
return
|
||||
}
|
||||
//依据key, 从depsMap中取出value, 该value是一个ReactiveEffect类型的数据
|
||||
const effect = depsMap.get(key) as ReactiveEffect
|
||||
if (!effect) {
|
||||
const dep: Dep | undefined = depsMap.get(key)
|
||||
if (!dep) {
|
||||
return
|
||||
}
|
||||
//执行effect中保存的fn函数
|
||||
effect.fn()
|
||||
triggerEffects(dep)
|
||||
}
|
||||
|
||||
/**
|
||||
* 依次触发dep中保存的依赖
|
||||
* @param dep
|
||||
*/
|
||||
export function triggerEffects(dep: Dep) {
|
||||
const effects = isArray(dep) ? dep : [...dep]
|
||||
//依次触发依赖
|
||||
for (const effect of effects) {
|
||||
triggerEffect(effect)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发指定依赖
|
||||
* @param effect
|
||||
*/
|
||||
export function triggerEffect(effect: ReactiveEffect) {
|
||||
effect.run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user