目錄
依賴收集的完整實現
trackEffects:建立雙向依賴關系
觸發更新的完整實現
完整的響應式流程
為什么使用 Map 而不是 Set?
總結
在上一篇文章中,我們介紹了 Vue3 響應式系統的基本原理和 activeEffect 的作用。現在,我們將深入探討完善后的依賴追蹤和觸發更新機制,特別是 track、 trigger、 trackEffects 和 triggerEffects 函數的實現,以及 ReactiveEffect 類中新增的屬性。
class ReactiveEffect {_trackId = 0; // 當前的 effect 執行了幾次deps = []; // 當前的 effect 依賴了哪些屬性_depsLength = 0; // 當前的 effect 依賴的屬性有多少個public active = true; //默認是響應式的constructor(public fn, public scheduler) {}// ...
}
這些新增的屬性有重要的作用:
- _trackId:記錄 effect 執行的次數,用于優化依賴收集
- deps:存儲當前 effect 依賴的所有屬性的依賴集合
- _depsLength:記錄依賴的屬性數量,避免頻繁計算數組長度
依賴收集的完整實現
// 存儲依賴收集的關系
const targetMap = new WeakMap();export const createDep = (cleanUp, key) => {const dep = new Map() as any; //創建的收集器還是一個mapdep.cleanUp = cleanUp; //清理方法dep.name = key; //收集器名稱return dep;
};export function track(target, key) {if (activeEffect) {let depsMap = targetMap.get(target);if (!depsMap) {targetMap.set(target, (depsMap = new Map()));}let dep = depsMap.get(key);if (!dep) {depsMap.set(key, (dep = createDep(() => depsMap.delete(key), key)));}trackEffects(activeEffect, dep);console.log(targetMap);}
}
與之前相比,有幾個重要的變化:
- 依賴集合從 Set 變成了 Map,這允許我們存儲更多信息
- 使用