返回

深入理解vue3 effect 深入解析响应式系统

前端

一、effect 是什么?

我们从一个最简单的示例开始,看看effect的用法和简单含义。

const count = ref(0);
const fn = ()=>{
  count.value++;
};

const stop = effect(fn); // 返回一个stop函数

stop(); // 调用stop函数,则不会再执行fn函数。

可以看到,effect把一个函数作为参数,返回一个stop函数。stop被调用时,该函数不再被执行。

那么,effect做了什么呢?

其实,effect就是响应式系统的核心,我们来模拟下它做了什么。

let active = 1;// active是当前effect的标识

const effect = (fn) => { // effect接收一个参数fn,用来执行fn函数。
  active++; // 当有新的effect时,我们就增加active的值。
  const res = fn(); // 执行fn函数,并返回结果。
  active--; // 当effect执行完毕时,我们就让active的值减一。
  return res; // 返回结果。
};

const count = ref(0);
const fn = ()=>{
  count.value++;
};

effect(fn); // active变为2,然后fn执行,count变为1。
effect(fn); // active变为3,然后fn执行,count变为2。

stop(); // active变回1,然后fn执行,count不变。

从上面我们可以看出,effect函数内部有一个active变量,用来记录当前激活的effect函数。

当我们调用effect函数时,我们就让active的值加1,然后执行fn函数,然后让active的值减1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够知道当前激活的effect函数了。

同时,当我们调用stop函数时,我们就让active的值减1,然后让fn函数执行,然后让active的值加1。

这样,我们就能够