vue3 computed详解
创建computed我们知道,computed可以传入两个参数作为computed值的getter和setter, 也可以传入一个getter函数, 此时vue会自动生成一个warn函数来作为创建computed的setterComputedRefImpl类我们使用computed时, 会使用传入的getter和setter创建一个ComputedRefImpl的实例对象, 这个实例对象缓存com
-
创建computed
我们知道,computed可以传入两个参数作为computed值的getter和setter, 也可以传入一个getter函数, 此时vue会自动生成一个warn函数来作为创建computed的setter -
ComputedRefImpl类
我们使用computed时, 会使用传入的getter和setter创建一个ComputedRefImpl的实例对象, 这个实例对象缓存computed的值,并作为target被响应式系统进行依赖收集,实际上在项目中依赖computed的订阅者依赖的都是ComputedRefImpl对象的实例 -
computed是如何实现懒加载的?
class ComputedRefImpl { constructor(getter, _setter, isReadonly) { this._setter = _setter; this._dirty = true; this.__v_isRef = true; this.effect = effect(getter, { lazy: true, scheduler: () => { if (!this._dirty) { this._dirty = true; trigger(toRaw(this), "set" /* SET */, 'value'); } } }); this["__v_isReadonly" /* IS_READONLY */] = isReadonly; } get value() { // the computed ref may get wrapped by other proxies e.g. readonly() #3376 const self = toRaw(this); if (self._dirty) { self._value = this.effect(); self._dirty = false; } track(self, "get" /* GET */, 'value'); return self._value; } set value(newValue) { this._setter(newValue); } }
上面为ComputedRefImpl 源代码, 在创建一个ComputedRefImpl的时候,实例对象中会有一个_dirty 用于表示是否需要计算computed,还会绑定一个effect用于在computed依赖变动时调用
-
effect()会创建一个computed的依赖的订阅者, 返回一个执行函数, 第一个参数为传入的函数用于执行更新, 第二个参数为options,lazy为延迟执行,(在依赖收集中,effect传入的函数会立即执行一次来完成依赖收集),computed的lazy为true不会立即执行
-
当computed的订阅者触发实例getter的时候,执行effect返回的函数, 得到computed的值,触发computed的依赖收集,_dirty设置为false,并缓存在ComputedRefImpl实例中。如果依赖项发生改变,就会调用effect把_dirty属性设置为true,并触发ComputedRefImpl的订阅者,触发getter,完成新的计算
更多推荐
所有评论(0)