介绍
开头继续感谢崔大的mini-vue 项目。
强烈建议大家把项目 down 下来,运行一下,看VUE3 的整体运行逻辑。
今天我们就来实现 effect 里面的 stop 逻辑
stop 逻辑
首先我们要的 stop ,最终效果是,当我们调用 stop 这个函数后,就不再更新值了。 但是我们可以手动调用 runner,这样子还会继续更新。
也就是当我们调用 stop 的时候,需要从effect 从 deps 移除。这样子就不会更新值了。
以下代码就是我们 stop 的核心逻辑了,直接遍历 effect。deps。然后 dep.delete 当前的effect 就可以了。
首先我们需要的是在track里面把我们的 dep收集起来。
activeEffect.deps.push(dep)
下面就是在activeEffect里面实现 stop 方法,当调用的时候,删除 effect
class ReactiveEffect {
deps = [];
stop() {
cleanupEffect(this);
}
}
function cleanupEffect(effect) {
effect.deps.forEach((dep: any) => {
dep.delete(effect)
})
完成之后可以开始稍微优化一下 stop 现在的每次调用stop 的时候,都会去清空,但是实际上我们只需要清空一次。 我们使用一个变量active记录一下
class ReactiveEffect {
active = true;
stop() {
if (this.active) {
cleanupEffect(this);
this.active = false
}
}
}
onStop 逻辑
首先声明一下这个onStop,是可以返回任何东西的。
然后我们执行 stop的时候,如果有onStop,就调用 onStop。
class ReactiveEffect {
onStop?: () => void;
stop() {
if (this.active) {
cleanupEffect(this);
if (this.onStop) {
this.onStop();
}
this.active = false
}
}
}
然后我们在effect里面处理一下
因为 onStop 是通过 options 传进来的,所以我们是需要options和_effect 合并起来就可以了
object.assign(_effect, options)
结尾
项目已经放到我的 GitHub 上面了,欢迎大家去start。
本次 commit地址:github.com/moyuhaokan/…
我的项目地址:github.com/moyuhaokan/…
再次推荐崔大的项目:github.com/cuixiaorui/…