js
/**
* Depend类用于管理依赖关系和通知依赖更新
*/
class Depend {
/**
* 构造函数初始化依赖集合
*/
constructor() {
this.reactiveFns = new Set()
}
/**
* 添加依赖函数
*/
depend() {
if (activeEffect) this.reactiveFns.add(activeEffect)
}
/**
* 通知所有依赖函数更新
*/
notify() {
this.reactiveFns.forEach(fn => fn?.())
}
}
/**
* 当前活跃的Effect函数
*/
let activeEffect = null
/**
* 监视Effect函数,执行并管理副作用更新
* @param {Function} fn 要监视的Effect函数
*/
function watchEffect(fn) {
activeEffect = fn
fn()
activeEffect = null
}
/**
* 用于存储目标对象及其属性的依赖关系映射
*/
const targetMap = new WeakMap()
/**
* 获取目标对象属性的依赖关系
* @param {Object} target 目标对象
* @param {string} key 目标对象的属性键
* @returns {Depend} 依赖关系实例
*/
function getDep(target, key) {
let depsMap = targetMap.get(target)
if (!depsMap) {
depsMap = new Map()
targetMap.set(target, depsMap)
}
let dep = depsMap.get(key)
if (!dep) {
dep = new Depend()
depsMap.set(key, dep)
}
return dep
}
/**
* 创建响应式对象
* @param {Object} obj 需要变成响应式的对象
* @returns {Object} 响应式对象
*/
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
const dep = getDep(target, key)
dep.depend()
return Reflect.get(target, key, receiver)
},
set(target, key, newValue, receiver) {
Reflect.set(target, key, newValue, receiver)
const dep = getDep(target, key)
dep.notify()
}
})
}
// 创建两个响应式对象
const info = reactive({ name: 'jingyou', age: 22 })
const info2 = reactive({ name: 'shihang', age: 23 })
// 监视info和info2的name属性
watchEffect(() => {
console.log(info.name) // jingyou
})
watchEffect(() => {
console.log(info2.name) // shihang
})
// 监视info的age和name属性, info2的age属性
watchEffect(() => {
console.log(info.age, info2.age, info.name) // 22 23 jingyou
})
// 更新响应式对象的属性值
info.name = '荆友' // 荆友 // 22 23 荆友
info2.name = '仕航' // 仕航
info.age = 24 // 24 23 荆友
info2.age = 25 // 24 25 荆友