// 当前的依赖函数
let currentEffect;
// 使用依赖的类
class Dep {
constructor(value) {
this.deps = new Set();
this._value = value;
}
get value() {
this.depend()
return this._value
}
set value(val) {
this._value = val;
this.notice()
}
depend() {
if (currentEffect) {
this.deps.add(currentEffect)
}
}
notice() {
this.deps.forEach(effect => {
effect()
})
}
}
function ref(Raw) {
const dep = new Dep(Raw)
return {
get value() {
return dep.value
},
set value(val) {
dep.value = val
}
}
}
// const dep = new Dep(10);
function effectWatch(effect) {
currentEffect = effect;
// 此处只需要调用effect来进行以来收集,目的是读取依赖的值触发get
effect();
// dep.depend();
currentEffect = null;
}
// 全局的响应式map
const targetDeps = new Map()
// 使用map是因为它的键可以是任何数据类型包括对象
function getDep(target, key) {
let deps = targetDeps.get(target);
if (!deps) {
deps = new Map()
targetDeps.set(target, deps)
}
let dep = deps.get(key);
if (!dep) {
dep = new Dep(target[key])
deps.set(key, dep)
}
return dep
}
function reactive(Raw) {
return new Proxy(Raw, {
get(target, key) {
//如果拿到的值是一个对象那么就进行递归代理
if (typeof target[key] === "object") {
return reactive(target[key])
}
const dep = getDep(target, key)
dep.depend()
return Reflect.get(target, key)
},
set(target, key, value) {
if (typeof target[key] === "object") {
return reactive(target[key])
}
const dep = getDep(target, key)
const result = Reflect.set(target, key, value)
dep.notice()
return result
}
})
}
const obj = {
zhangsan: {
age: 10,
gender: {
age: 19
}
}
}
const user = reactive(obj);
// 使用b、c两个变量
let b, c;
effectWatch(() => {
b = user.zhangsan.gender.age + 100;
console.log("b", b)
c = user.zhangsan.age
console.log("c", c)
})
// user.zhangsan.gender.age = 200;
user.zhangsan.age = 15
Vue reactive简单实现原理
最新推荐文章于 2024-10-30 21:23:36 发布
1万+

被折叠的 条评论
为什么被折叠?



