《Vue.js设计与实现》读书笔记(二)

computed实现

const data = {text: 'hello world', ok: true, foo: 1, bar: 2};

const bucket = new WeakMap();
let activeEffect;
let effectStack = [];

const obj = new Proxy(data, {
    get(target, key){
        track(target, key);
        return target[key];
    },
    set(target, key, newVal) {
        target[key] = newVal;
        trigger(target, key);
    }
})
function track(target, key){
    if(!activeEffect) return target[key];
    let depsMap = bucket.get(target);
    if(!depsMap) {
        bucket.set(target, (depsMap = new Map()))
    }
    let deps = depsMap.get(key);
    if(!deps) {
        depsMap.set(key, (deps = new Set()));
    }
    deps.add(activeEffect);
    activeEffect.deps.push(deps);
}
function trigger(target, key) {
    const depsMap = bucket.get(target);
    if(!depsMap)return;
    const effects = depsMap.get(key);
    const effectsSet = new Set();
    effects&& effects.forEach(fn => {
        if(activeEffect !== fn) {
            effectsSet.add(fn);
        }
    })
    effectsSet.forEach(fn => {
        fn.options.scheduler ? fn.options.scheduler(fn) : fn();
    });
}
function cleanup(effectFn) {
    for(let i=0; i< effectFn.deps.length; i++) {
        const deps = effectFn.deps[i];
        deps.delete(effectFn);
    }
    effectFn.deps.length = 0;
}
const effect = (fn, options={})=>{
    const  effectFn = () =>{
        cleanup(effectFn);
        activeEffect = effectFn;
        effectStack.push(effectFn);
        const res = fn();
        effectStack.pop();
        activeEffect = effectStack[effectStack.length -1];
        return res;
    }
    effectFn.options = options;
    effectFn.deps = [];
    if(!options.lazy) {
        effectFn();
    }
    return effectFn;
}

function computed(getter) {
    let value;
    let dirty = true;
    const effectFn = effect(getter, {lazy: true, scheduler(){
        dirty = true;
        trigger(obj, 'value');
        }});
    const obj = {
        get value(){
            if(dirty){
                value = effectFn();
                dirty = false;
                track(obj, 'value');
            }
            return value;
        }
    };
    return obj;
}

const sumRes = computed(()=> {
    console.log('computed');
    return (obj.foo + obj.bar);
});
effect(()=> console.log(sumRes.value));
obj.foo = 5;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值