2025.09.18
模块解耦:reactivity 架构的逻辑拆分
🏛️ 架构目标:高复用与单一职责
为了提升系统性能和遵循单一职责原则,reactivity 模块的实现采取了高度解耦的架构。核心思路是将 Proxy 的拦截逻辑(get/
set)从创建函数中抽离出来,形成一个独立的、可共享的 handlers 模块。
设计优势:
- 性能提升: 所有代理实例共享同一份
mutableHandlers对象, 避免每次创建代理时都重复创建和初始化handlers对象的开销 - 高复用性: 不同的响应式 API(如
reactiveshallowReactive) 可以轻松复用或组合这些基础handlers
📦 模块职责划分
reactivity 核心功能被清晰地划分为三个主要模块:
| 模块 | 核心职责 | 关键功能 |
|---|---|---|
reactive.ts | 代理创建与身份识别 | reactive 函数、缓存机制(reactiveMap)、身份验证(isReactive) |
baseHandlers.ts | Proxy 拦截 | 拦截 get/set、实现深度代理、ref 自动解包、值变化对比 |
dep.ts | 依赖收集与派发 | 依赖存储(targetMap、依赖收集(track)、派发更新(trigger) |
- 核心拦截器:
baseHandlers.tsget拦截: 收集、解包、递归代理export const mutableHandlers: ProxyHandler<any> = { get(target, key, receiver) { track(target, key) // 📌 1. 依赖收集 const res = Reflect.get(target, key, receiver) if (isRef(res)) { return res.value // 📌 2. Ref 自动解包 } if (isObject(res)) { return reactive(res) // 📌 3. 深度代理 (惰性递归) } return res } // ... }set拦截: 值同步与值变化对比export const mutableHandlers: ProxyHandler<any> = { // ... set(target, key, newValue, receiver) { const oldValue = target[key] // 📌 1. Ref 同步修改:如果旧值是 ref,且新值不是 ref,直接修改 ref.value if (isRef(oldValue) && !isRef(newValue)) { oldValue.value = newValue return true } const res = Reflect.set(target, key, newValue, receiver) // 📌 2.值真正变化才触发更新 if (hasChanged(newValue, oldValue)) { trigger(target, key) } return res } } - 依赖管理中心:
dep.ts
该模块专注于维护target、key与effect之间的三层映射关系,确保依赖追踪的精准性。
结构和职责targetMap: 全局WeakMap, 存储target -> depsMap的映射DepClass: 通过双向链表(subs), 存储单个属性的所有依赖track: 确保activeSub被链接到target[key]对于的Deptrigger: 通过targetMap找到目标Dep并调用propagate派发更新
// dep.ts 摘要 export const targetMap: WeakMap<Target, any> = new WeakMap<Target, any>() export function track(target: object, key: unknown) { // ... 查找 depsMap, Dep, 并调用 link(dep, activeSub) } export function trigger(target: object, key: unknown) { // ... 通过 targetMap 查找 Dep, 并调用 propagate(dep.subs) } - 代理工厂:
reactive.ts该模块的核心职责是创建代理对象并维护缓存与身份识别,保证对象不被重复代理。// reactive.ts 摘要 const reactiveMap: WeakMap<object, any> = new WeakMap<object, any>() // target -> proxy 缓存 const reactiveSet: WeakSet<object> = new WeakSet<object>() // 代理对象身份集合 function createReactiveObject<T extends object>(target: T): T { // 1. 防止重复代理:如果是代理对象,直接返回 if (isReactive(target)) { return target } // 2. 缓存检查:如果已代理过,返回旧代理 const existingProxy = reactiveMap.get(target) if (existingProxy) { return existingProxy } const proxy = new Proxy(target, mutableHandlers) // 共享 handlers // 3. 存储缓存和身份 reactiveMap.set(target, proxy) reactiveSet.add(proxy) return proxy } export function isReactive(target: object) { return reactiveSet.has(target) // 身份识别 }