使用对象的 set/get 方法 模拟实现 vue3 ref 单数据响应
const targetMap = new Map();
let currentEffect;
class Dep {
constructor(val) {
this.effects = new Set();
this._val = val;
}
get value() {
this.depend();
return this._val;
}
set value(newVal) {
this._val = newVal;
this.notice();
}
// 收集依赖
depend() {
if (currentEffect) {
this.effects.add(currentEffect);
}
}
// 触发依赖
notice() {
this.effects.forEach((effect) => {
effect();
});
}
}
function effectWatch(effect) {
// 依赖收集
currentEffect = effect;
effect();
currentEffect = null;
}
const dep = new Dep(10);
let b;
effectWatch(() => {
b = dep.value + 10;
console.log(b); // 初始值打印为 10 dep.value修改后打印为 20
});
// 值变更 通知 触发依赖 更新变量
dep.value = 20;
使用 Proxy/Reflect 实现 vue3 reactive 函数的实现原理
const targetMap = new Map(); //存储指定key的对象
let currentEffect;
class Dep {
constructor(val) {
this.effects = new Set();
this._val = val;
}
// 收集依赖
depend() {
if (currentEffect) {
this.effects.add(currentEffect);
}
}
// 触发依赖
notice() {
this.effects.forEach((effect) => {
effect();
});
}
}
function effectWatch(effect) {
// 依赖收集
currentEffect = effect;
effect();
currentEffect = null;
}
function getDep(target, key) {
// key - dep依赖收集
let depsMap = targetMap.get(target);
if (!depsMap) {
depsMap = new Map();
targetMap.set(target, depsMap);
}
let dep = depsMap.get(key);
if (!dep) {
dep = new Dep();
depsMap.set(key, dep);
}
return dep;
}
function reactive(raw) {
//代理对象所有属性
return new Proxy(raw, {
get(target, key) {
const dep = getDep(target, key);
// 依赖收集
dep.depend();
return Reflect.get(target, key);
},
set(target, key, value) {
// 触发依赖
const dep = getDep(target, key);
const result = Reflect.set(target, key, value);
dep.notice();
return result;
},
});
}
const user = reactive({
age: 19,
});
let double;
effectWatch(() => {
double = user.age;
console.log(double);
});
user.age = 20;