feat(effects): 实现响应式依赖收集和触发机制
- 创建targetMap WeakMap用于存储响应式对象及其依赖映射关系 - 实现track函数用于收集依赖并建立target-key-effect的映射 - 实现trigger函数用于触发指定key的依赖更新 - 在track中通过activeEffect判断是否需要收集依赖 - 添加详细的JSDoc注释说明参数和功能 - 示例页面中添加定时器验证响应式更新效果
This commit is contained in:
@@ -1,3 +1,13 @@
|
|||||||
|
type KeyToDepMap = Map<any, ReactiveEffect>
|
||||||
|
/**
|
||||||
|
* 收集所有依赖的WeakMap实例
|
||||||
|
* key: 响应性对象
|
||||||
|
* value: Map对象
|
||||||
|
* key: 响应性对象的指定属性
|
||||||
|
* value:指定对象的指定属性的执行函数
|
||||||
|
*/
|
||||||
|
const targetMap = new WeakMap<any, KeyToDepMap>()
|
||||||
|
|
||||||
export function effect<T = any>(fn: () => T) {
|
export function effect<T = any>(fn: () => T) {
|
||||||
const _effect = new ReactiveEffect(fn)
|
const _effect = new ReactiveEffect(fn)
|
||||||
_effect.run()
|
_effect.run()
|
||||||
@@ -15,19 +25,38 @@ export class ReactiveEffect<T = any> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 收集依赖
|
* 收集依赖
|
||||||
* @param target
|
* @param target WeakMap的key
|
||||||
* @param key
|
* @param key key代理对象的key, 当依赖被触发时,需要根据该key获取
|
||||||
*/
|
*/
|
||||||
export function track(target: object, key: unknown) {
|
export function track(target: object, key: unknown) {
|
||||||
console.log('收集依赖 track')
|
if (!activeEffect) return
|
||||||
|
//尝试从 targetMap 中, 根据target获取map
|
||||||
|
let depsMap = targetMap.get(target)
|
||||||
|
//如果获取到的map不存在,则生成新的map对象, 并把该对象赋值给对应的value
|
||||||
|
if (!depsMap) {
|
||||||
|
targetMap.set(target, (depsMap = new Map()))
|
||||||
|
}
|
||||||
|
//为指定map, 指定key, 设置回调函数
|
||||||
|
depsMap.set(key, activeEffect)
|
||||||
|
console.log(targetMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 触发依赖
|
* 触发依赖
|
||||||
* @param target
|
* @param target WeakMap的key
|
||||||
* @param key
|
* @param key key代理对象的key, 当依赖被触发时,需要根据该key获取
|
||||||
* @param newValue
|
|
||||||
*/
|
*/
|
||||||
export function trigger(target: object, key: unknown, newValue: unknown) {
|
export function trigger(target: object, key: unknown, newValue: unknown) {
|
||||||
console.log('触发依赖 trigger')
|
//依据target获取存储的map实例
|
||||||
|
const depsMap = targetMap.get(target)
|
||||||
|
if (!depsMap) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//依据key, 从depsMap中取出value, 该value是一个ReactiveEffect类型的数据
|
||||||
|
const effect = depsMap.get(key) as ReactiveEffect
|
||||||
|
if (!effect) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//执行effect中保存的fn函数
|
||||||
|
effect.fn()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,5 +16,8 @@
|
|||||||
effect(()=>{
|
effect(()=>{
|
||||||
document.querySelector('#app').innerText=obj.name
|
document.querySelector('#app').innerText=obj.name
|
||||||
})
|
})
|
||||||
|
setTimeout(()=>{
|
||||||
|
obj.name='李四'
|
||||||
|
},2000)
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user