简单实现 五
问题分析,当 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";
});