返回

拨开Vue3源码迷雾,探究computed计算属性的奥秘

前端

在Vue2中,我们对计算属性已经了如指掌。那么,Vue3中的计算属性又有何不同之处呢?在这篇文章中,我们将以Vue3源码为基础,带领大家深入探索计算属性的运行流程,探究其背后隐藏的精妙设计和实现细节。

一、computed函数简介

Vue3为我们提供了computed函数,它作为计算属性的API,允许我们使用两种类型的参数:

  1. getter函数:一种用于获取计算属性值的函数。
  2. 对象:包含getter函数和可选的setter函数的对象。

二、computed函数的内部实现

为了更好地理解computed函数的工作原理,我们首先需要了解其内部实现。在Vue3源码中,computed函数位于packages/reactivity/src/computed.ts文件中。

1. 定义computedRef对象

export interface ComputedRef<T> extends WritableComputedRef<T> {
  readonly value: T;
}

computedRef对象是计算属性的基础,它包含了计算属性值以及一些元数据。其中,value属性保存着计算属性的当前值。

2. 定义effectScope对象

export const effectScope = createEffectScope(true /* detached */);

effectScope对象是一个作用域,它用于将计算属性的getter函数与响应式依赖项联系起来。

3. 定义computed函数

export function computed<T>(getterOrOptions: GetterOrOptions<T>): ComputedRef<T> {
  let getter: Function | undefined;
  let setter: Function | undefined;

  if (isRef(getterOrOptions)) {
    // getterOrOptions is a ref
    getter = () => getterOrOptions.value;
  } else if (isFunction(getterOrOptions)) {
    // getterOrOptions is a function
    getter = getterOrOptions;
  } else if (isObject(getterOrOptions)) {
    // getterOrOptions is an object
    getter = getterOrOptions.get;
    setter = getterOrOptions.set;
  } else {
    throw new Error(`Invalid getter: ${getterOrOptions}`);
  }

  const computed = {
    // ...
  };

  return computed;
}

computed函数首先根据传入的参数类型判断是getter函数还是对象,然后分别处理。接下来,它会创建一个computed对象,其中包含了计算属性的getter函数、setter函数等信息。

4. 调用effect函数

effect(runner);

effect函数用于将计算属性的getter函数与响应式依赖项联系起来。当依赖项发生改变时,effect函数会重新执行getter函数,更新计算属性的值。

三、computed计算属性的运行流程

现在,我们已经了解了computed函数的内部实现,接下来让我们来看看计算属性的运行流程。

1. 调用computed函数创建computedRef对象

首先,我们需要调用computed函数创建一个computedRef对象。

const count = computed(() => state.count);

2. effect函数收集依赖项

当我们访问计算属性的值时,effect函数会被触发,它会收集计算属性的依赖项。

const countValue = count.value;

3. 计算属性值发生改变时重新计算

当计算属性的依赖项发生改变时,effect函数会重新执行getter函数,更新计算属性的值。

state.count++;

4. 触发视图更新

当计算属性的值发生改变时,视图会自动更新。

<p>{{ count }}</p>

四、总结

通过对Vue3源码的分析,我们对计算属性的原理和实现有了更深入的理解。计算属性作为Vue3中一种强大的工具,能够帮助我们构建响应式、动态的界面。希望这篇文章能够为您带来新的启发和见解,帮助您更好地使用Vue3开发应用程序。