实现 effect & reactive 依赖收集&触发依赖
创建effect.spec.ts单测
import { reactive } from "../reactive"
import { effect } from "../effect"
describe('effect', () => {
it('happy path', () => {
const user = reactive({
age: 10,
})
let nextAge
effect(() => {
nextAge = user.age + 1
})
expect(nextAge).toBe(11)
// update
user.age++
expect(nextAge).toBe(12)
})
})
//effect.ts
class ReactiveEffect{
private _fn
constructor(fn){
this._fn = fn
}
run(){
activeEffect = this
this._fn()
}
}
export function effect(fn){
const _effect = new ReactiveEffect(fn)
_effect.run()
}
let activeEffect
const targetMap = new WeakMap()
//收集依赖
export function track(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 Set()
depsMap.set(key,dep)
}
//判断是否已经收集过依赖,没有就直接添加
dep.add(activeEffect)
}
//触发依赖
export function trigger(target, key){
let depsMap = targetMap.get(target)
let deps = depsMap.get(key)
console.log(deps)
for(const effect of deps){
effect.run()
}
}
//reactive.ts
import { track,trigger } from "./effect"
export function reactive(raw){
return new Proxy(raw,{
get(target,key){
const res = Reflect.get(target,key)
//设置依赖
track(target, key)
return res
},
set(target,key,value){
const res = Reflect.set(target,key,value)
//触发依赖
trigger(target, key)
return res
}
})
}
执行yarn test effect
得到
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。