简单实现 五
问题分析,当 obj.ok = false; 时,此代码的 obj.text 的 关联 effect 函数还存在,当obj.text 发生变化时,还会触发 effect函数执行,此时 视图层 还是现实 not,触发不必要的变化了
const bucket = new WeakMap();const data = {ok: true, text: "hello world vue"};const track = (target, key) => { // [træk] 跟踪 if (!activeEffect) { return; } let depsMap = bucket.get(target); if (!depsMap) { bucket.set(target, (depsMap = new Map())); } let deps = depsMap.get(key); if (!deps) { depsMap.set(key, (deps = new Set())); } deps.add(activeEffect);};const trigger = (target, key) => { // [ˈtrɪɡə(r)] 触发 const depsMap = bucket.get(target); if (!depsMap) return; const effects = depsMap.get(key); effects && effects.forEach(fn => fn());};const obj = new Proxy(data, { get(target, key) { track(target, key); return target[key]; }, set(target, key, newVal) { target[key] = newVal; __key = key; trigger(target, key); return true; }});window.__self = obj;let __key;let activeEffect;function effect(fn) { activeEffect = fn; fn();}// 初始化effect(// 一个匿名的副作用函数() => { console.log(__key); document.body.innerText = obj.ok ? obj.text : "not";});setTimeout(() => { obj.text = "hello vue3";});
简单实现 六
const bucket = new WeakMap();window.__weakMap = bucket;const data = {ok: true, text: "hello world vue"};const track = (target, key) => { // [træk] 跟踪 if (!activeEffect) { return; } let depsMap = bucket.get(target); if (!depsMap) { bucket.set(target, (depsMap = new Map())); } let deps = depsMap.get(key); if (!deps) { depsMap.set(key, (deps = new Set())); } deps.add(activeEffect); activeEffect.desp.push(deps);};const trigger = (target, key) => { // [ˈtrɪɡə(r)] 触发 const depsMap = bucket.get(target); if (!depsMap) return; const effects = depsMap.get(key); const effectsToRun = new Set(effects); effectsToRun.forEach(effectFn => effectFn()); // effects && effects.forEach(fn => fn());};const obj = new Proxy(data, { get(target, key) { track(target, key); return target[key]; }, set(target, key, newVal) { target[key] = newVal; __key = key; trigger(target, key); return true; }});window.__self = obj;let __key;let activeEffect;function cleanup (effectFn) { for(let i = 0; i < effectFn.desp.length; i += 1) { const desp = effectFn.desp[i]; desp.delete(effectFn); } effectFn.desp.length = 0;}function effect(fn) { const effectFn = () => { cleanup(effectFn); activeEffect = effectFn; fn(); }; effectFn.desp = []; effectFn();}// 初始化effect(// 一个匿名的副作用函数() => { console.log(__key); document.body.innerText = obj.ok ? obj.text : "not";});setTimeout(() => { obj.text = "hello vue3";});