前言
这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情” 今天我们来分析vue3响应式最后一个核心api computed,中文名字叫计算属性。计算属性可以让我们的代码变得更优雅。需要注意的是,在刚创建的时候,computed不会立即执行。
正文
首先,我们来看computed的源码的大致结果。Comcomputed依赖于ComputedRefImpl这个类。
从computed的参数来看,可以只传入getter,当然,也可以同时传入getter和setter。
核心实现类ComputedRefImpl
接下来我们来看核心实现类ComputedRefImpl,如下图所示,可以发现有像dep这种可选的容器,以及readonly的一些属性,在这里我们可以看到在这里用到了effect里面的ReactiveEffect。与此同时,定义了_dirty这个属性,它代表值有没有发生改变,如果没发生改变的话,那么就不会执行计算属性;反之,就不会执行计算属性。
get操作
接下来我们来看get操作,在get里面,用toRaw取this里面的一些值,这里面用到了ref里面的trackRefValue这个来进行收集依赖,在这里面我们可看到对dirty做了判断,与此同时,调用了effect里面的run方法,最后把值直接返回出去。
set操作
set操作的话其实就是对值进行set操作把
constructor
接下来我们来看constructor,翻阅源码的话,在构造器里面可以发现还是基于去new ReactiveEffect这个类去实现的。
constructor(
getter: ComputedGetter<T>,
private readonly _setter: ComputedSetter<T>,
isReadonly: boolean,
isSSR: boolean
) {
this.effect = new ReactiveEffect(getter, () => {
if (!this._dirty) {
this._dirty = true
triggerRefValue(this)
}
})
this.effect.computed = this
this.effect.active = this._cacheable = !isSSR
this[ReactiveFlags.IS_READONLY] = isReadonly
}
computed方法
最后我们来看computed的实现方法,可以发现是基于上面那个类进行实现的,与此同时,在这里可以发现computed最后返回的是一个只读的ref。
结尾
响应式是vue的发动机,其实结合单测调试并慢慢看源码的话,会发现并不难。到这里,vue3的响应式模块的原理就结束了,这一部分写完之后,下一部分我们就要开始说vue3的运行时的模块了。