赞
踩
接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象。
import { isFunction } from "@vue/shared"; import { activeEffect, ReactiveEffect, trackEffects, triggerEffects } from "./effect"; class ComputedRefImpl { public effect; public _value; public dep; public _dirty = true; constructor(getter,public setter) { this.effect = new ReactiveEffect(getter,()=>{ if(!this._dirty){ // 依赖的值变化更新dirty并触发更新 this._dirty = true; triggerEffects(this.dep) } }); } get value(){ // 取值的时候进行依赖收集 if(activeEffect){ trackEffects(this.dep || (this.dep = new Set)); } if(this._dirty){ // 如果是脏值, 执行函数 this._dirty = false; this._value = this.effect.run(); } return this._value; } set value(newValue){ this.setter(newValue) } } export function computed(getterOrOptions) { const onlyGetter = isFunction(getterOrOptions); // 传入的是函数就是getter let getter; let setter; if (onlyGetter) { getter = getterOrOptions; setter = () => { } } else { getter = getterOrOptions.get; setter = getterOrOptions.set; } // 创建计算属性 return new ComputedRefImpl(getter, setter)
创建ReactiveEffect时,传入
scheduler
函数,稍后依赖的属性变化时调用此方法!
export function triggerEffects(effects) { effects = new Set(effects); for (const effect of effects) { if (effect !== activeEffect) { // 如果effect不是当前正在运行的effect if (effect.scheduler) { effect.scheduler() } else { effect.run(); // 重新执行一遍 } } } } export function trackEffects(dep) { // 收集dep 对应的effect let shouldTrack = !dep.has(activeEffect) if (shouldTrack) { dep.add(activeEffect); activeEffect.deps.push(dep); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。