vue computed方法

//类型判断函数
const isFunction = (val) => typeof val === 'function';

function computed(getterOrOptions, debugOptions) {
    let getter;
    let setter;
    if (isFunction(getterOrOptions)) {
        getter = getterOrOptions;
        //computed不能执行设置值的操作
        // setup(){
        //     onMounted(()=>{
        //       num.value = 2
        //       console.log(num)
        //     })
        //     const num = computed(()=>{
        //       return 1
        //     })
        // }
        //这个时候控制台会提示错误 并且num的值也不会改变
        setter = () => {console.warn('Write operation failed: computed value is readonly');}
    }
    else {
        getter = getterOrOptions.get;
        setter = getterOrOptions.set;
    }
    // isFunction(getterOrOptions) 值为true
    console.log(!getterOrOptions.set)  //传入的值为true 因为getterOrOptions.set 值为undefined 
    const cRef = new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);

    //外部传入的debug操作模式 平时用的不多
    if (debugOptions) {
        cRef.effect.onTrack = debugOptions.onTrack;
        cRef.effect.onTrigger = debugOptions.onTrigger;
    }
    return cRef;
}
//转换成原始值
function toRaw(observed) {
    const raw = observed && observed["__v_raw"];
    return raw ? toRaw(raw) : observed;
}
let shouldTrack = true;
let activeEffect;
//函数初始化时一般返回值为 false
function isTracking() {
    return shouldTrack && activeEffect !== undefined;
}
function trackRefValue(ref) {
    //第一次进来不执行
    if (isTracking()) {
        console.log('创建dep')
        ref = toRaw(ref);
        if (!ref.dep) {
            ref.dep = createDep();
        }
        {
            trackEffects(ref.dep, {
                target: ref,
                type: "get" /* GET */,
                key: 'value'
            });
        }
    }
}
function trackEffects(dep, debuggerEventExtraInfo) {
    let shouldTrack = false;
    if (effectTrackDepth <= maxMarkerBits) {
        if (!newTracked(dep)) {
            dep.n |= trackOpBit; // set newly tracked
            shouldTrack = !wasTracked(dep);
        }
    }
    else {
        // Full cleanup mode.
        shouldTrack = !dep.has(activeEffect);
    }
    if (shouldTrack) {
        dep.add(activeEffect);
        activeEffect.deps.push(dep);
        if (activeEffect.onTrack) {
            activeEffect.onTrack(Object.assign({
                effect: activeEffect
            }, debuggerEventExtraInfo));
        }
    }
}

//实例化计算属性的类 传入getter 和setter 
class ComputedRefImpl {
    constructor(getter, _setter, isReadonly) {
        this._setter = _setter; //把setter函数传进来给实例
        this.dep = undefined;
        this._dirty = true;
        this.__v_isRef = true;  //设置了 __v_isRef属性 
        this.effect = new ReactiveEffect(getter, () => {
            //初始化的构造函数这一段代码不执行 获取值的时候就会被执行
            if (!this._dirty) {
                this._dirty = true;
                triggerRefValue(this);
            }
        });
        this["__v_isReadonly" /* IS_READONLY */] = isReadonly;   //设置为只读属性
        this.fn = getter   //这个是自己添加的一种实现方式
    }
    get value() {
        console.log('获取value的值')
        // the computed ref may get wrapped by other proxies e.g. readonly() #3376
        const self = toRaw(this);
        console.log(self._value,'拦截到的值')
        trackRefValue(self);
        if (self._dirty) {
            self._dirty = false;
            self._value = self.effect.run();
            // self._value = self.fn() //函数直接调用getter 不去进行栈的track跟踪    console.log(num.value,'返回的num值')
            //同样也可以获取到 num.value设置的值
        }
        return self._value;
    }
    set value(newValue) {
        this._setter(newValue);
        //如果想要调用set 拦截value操作 就会直接执行下面传入的函数
        // setter = () => {console.warn('Write operation failed: computed value is readonly');}
    }
}
let activeEffectScope;     //值为undefined
const effectStack = []
const trackStack = []
let trackOpBit = 1;
let effectTrackDepth = 0;
const maxMarkerBits = 30;

function recordEffectScope(effect, scope) {
    console.log(effect,'effect传入的this对象')
    console.log(scope,'传入的scope') //控制台输出undefined
    scope = scope || activeEffectScope;   //这里可以得到scope为undefined 
    //这段代码不被执行,因为scope为undefined
    if (scope && scope.active) {
        scope.effects.push(effect);
    }
}
function enableTracking() {
    trackStack.push(shouldTrack);
    shouldTrack = true;
}
const initDepMarkers = ({ deps }) => {
    console.log(deps.length,'deps.length')  
    if (deps.length) {
        for (let i = 0; i < deps.length; i++) {
            deps[i].w |= trackOpBit; // set was tracked
        }
    }
}
function cleanupEffect(effect) {
    const { deps } = effect;
    if (deps.length) {
        for (let i = 0; i < deps.length; i++) {
            deps[i].delete(effect);
        }
        deps.length = 0;
    }
}

const wasTracked = (dep) => (dep.w & trackOpBit) > 0
const newTracked = (dep) => (dep.n & trackOpBit) > 0
const finalizeDepMarkers = (effect) => {
    const { deps } = effect;
    if (deps.length) {
        let ptr = 0;
        for (let i = 0; i < deps.length; i++) {
            const dep = deps[i];
            if (wasTracked(dep) && !newTracked(dep)) {
                dep.delete(effect);
            }
            else {
                deps[ptr++] = dep;
            }
            // clear bits
            dep.w &= ~trackOpBit;
            dep.n &= ~trackOpBit;
        }
        deps.length = ptr;
    }
}
function resetTracking() {
    const last = trackStack.pop();
    shouldTrack = last === undefined ? true : last;
}
class ReactiveEffect {
    //把getter 当作函数传进来 第二个箭头函数 
    constructor(fn, scheduler = null, scope) {
        console.log(scope,'scope')   //scope 没有传值的话就为undefined
        console.log(fn,'fn函数')
        console.log(scheduler,'scheduler回调函数')
        this.fn = fn;    //getter() 函数
        this.scheduler = scheduler;
        this.active = true;
        this.deps = [];
        recordEffectScope(this, scope);
    }
    run() {
        //不执行
        if (!this.active) {
            return this.fn();
        }
        //写入effectStack栈中
        console.log(!effectStack.includes(this),'effectStack的值')   //值为undefined
        if (!effectStack.includes(this)) {
            try {
                // effectStack.push((activeEffect = this));
                // console.log(effectStack,'effectStack')
                // enableTracking();
                // trackOpBit = 1 << ++effectTrackDepth;
                // console.log(trackOpBit,'trackOpBit字节数')
                // if (effectTrackDepth <= maxMarkerBits) {
                //     console.log('init')
                //     initDepMarkers(this);
                // }
                // else {
                //     cleanupEffect(this);
                // }
                console.log(this.fn(),'this.fn()函数')  //此处可以获取到计算属性的值
                return this.fn();
            }
            
            finally {
                if (effectTrackDepth <= maxMarkerBits) {
                    finalizeDepMarkers(this);
                }
                trackOpBit = 1 << --effectTrackDepth;
                resetTracking();
                effectStack.pop();
                const n = effectStack.length;
                activeEffect = n > 0 ? effectStack[n - 1] : undefined;

                console.log(activeEffect,'activeEffect的值')
            }
        }
    }
    // stop() {
    //     if (this.active) {
    //         cleanupEffect(this);
    //         if (this.onStop) {
    //             this.onStop();
    //         }
    //         this.active = false;
    //     }
    // }
}

var num = computed(()=>{
    return 'sssssssssssssssssssss'
})
console.log(num.value,'返回的num值')

调用setter()函数时

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值