Creates an effect scope object which can capture the reactive effects (i.e. computed and watchers) created within it so that these effects can be disposed together. For detailed use cases of this API, please consult its corresponding RFC.
意思就是EffectScope能收集一些effect,并且能统一去处理他们
const scope = effectScope() scope.run(() => { const doubled = computed(() => counter.value * 2) watch(doubled, () => console.log(doubled.value)) watchEffect(() => console.log('Count: ', doubled.value)) }) // to dispose all effects in the scope scope.stop()
export let activeEffectScope /** * * @param effect 传入的副作用函数,用来记录effect的层级包含关系 */ export function recordEffectScope(effect) { if (activeEffectScope && activeEffectScope.active) { activeEffectScope.effects.push(effect) } } // effectScope 收集子的scope class EffectScope { public effects = [] // 存放effect的列表 public parent public active = true public scopes = [] // 用来存储作用域 constructor(detached) { if (!detached && activeEffectScope) { activeEffectScope.scopes.push(this) } } run(fn) { if (this.active) { try { this.parent = activeEffectScope // 解决嵌套问题 activeEffectScope = this return fn() // 相当于scope.run 相当于里面的函数的返回值 } finally { activeEffectScope = this.parent } } } stop() { if (this.active) { this.active = false this.effects.forEach(effect => effect.stop()) } if (this.scopes) { this.scopes.forEach(scopeEffect => scopeEffect.stop()) } } } export function effectScope(detached = false) { return new EffectScope(detached) } // 这边又实现了一遍effect, 让effectScope可以记录effect
- new EffectScope,run回调函数里面的方法
- 将当前EffectScrop的实例挂载到全局,然后利用js单线程的优势,实现父子收集
- 暴露出一个recordEffectScope函数给ReactiveEffect,这样就能去收集利用ReactiveEffect创建的api(computed watch watchEffect等)的实例,挂载到当前EffectScope实例的scopes上面
- new EffectScope,stop执行
- 关闭当前的ReactiveEffect的响应式
- 关闭当前scrope的响应式