手写mini版本的Vue3--实现stop 功能

191 阅读1分钟

介绍

开头继续感谢崔大的mini-vue 项目。

项目地址:github.com/cuixiaorui/…

强烈建议大家把项目 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/…