Vue3源码 computed实现

124 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

Vue3 Computed源码实现

计算属性是Vue中常用的一个功能,它可以根据其它属性的值计算出一个新的值,从而简化模板中的复杂计算逻辑。

在Vue3中,计算属性的实现与Vue2有所不同。Vue3使用了一个新的方法来定义计算属性——computed()

下面是computed()的源码实现。

function computed(getterOrOptions) {
  const isReadonly = isFunction(getterOrOptions)
  const getter = isReadonly ? getterOrOptions : getterOrOptions.get
  const setter = isReadonly ? () => {} : getterOrOptions.set
  let dirty = true
  let value
  let computed
  function recompute() {
    if (dirty) {
      dirty = false
      value = getter()
    }
    track(computed, TrackOpTypes.GET, 'value')
    return value
  }
  function trigger() {
    dirty = true
    trigger(computed, TriggerOpTypes.SET, 'value')
  }
  computed = {
    __v_isRef: true,
    get value() {
      return recompute()
    },
    set value(newValue) {
      setter(newValue)
    }
  }
  return computed
}

函数说明

computed()函数接收一个函数或包含getset方法的对象作为参数,并返回一个对象,该对象具有value属性。

当调用computedObj.value时,将调用该计算属性的getter函数

当给computedObj.value赋值时,将调用该计算属性的setter函数。

计算属性的值将被缓存,只有当依赖项发生变化时,才会重新计算。

Vue3的计算属性实现支持异步计算属性,这意味着你可以在计算属性的getter函数中异步获取数据,并在数据准备好后更新计算属性的值。这是一个非常强大的功能。

实现细节

  1. 对于只有getter方法的计算属性,我们将其视为只读计算属性。
  2. 初始化时,将dirty设置为true,以确保计算属性的值在第一次访问时计算。
  3. recompute()函数用于重新计算计算属性的值。在计算属性的getter函数被调用时,我们需要将计算属性的依赖项添加到响应式系统中。
  4. trigger()函数用于标记计算属性的依赖项已经发生了变化,需要重新计算计算属性的值。
  5. 在计算属性对象上,我们需要添加一个__v_isRef属性,以确保计算属性可以被识别为一个ref对象。

以上是computed()的源码实现。需要注意的是,Vue3的计算属性实现使用了Proxy和Reflect。

希望本文能对你理解Vue3计算属性的实现有所帮助。