最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue3 响应式原理探索Part 5 - computed values 的实现

    正文概述 掘金(对马弹琴)   2021-06-10   540

    “这是我参与更文挑战的第10天,活动详情查看: 更文挑战”

    前文摘要

    通过之前的学习,我们已经通过 Proxy + Reflect 搭建出了一个基础的响应式实现,并探索了 ref 的原理和实现。

    • Vue3 响应式原理探索Part 1 - 20行代码实现响应式
    • Vue3 响应式原理探索Part 2 - 多重结构的响应式
    • Vue3 响应式原理探索Part 3 - Proxy + Reflect + activeEffect
    • Vue3 响应式原理探索Part 4 - ref 的原理和实现

    本文我们将学习 Computed Values 的实现。

    computed 用法

    回到之前 ref 的示例代码如下:

    let param = reactive({ width: 5, height: 2  });
    let size = 0;
    let newWidth = ref(0);
    
    effect(() => {
        newWidth.value = param.width * 2;
    });
    
    effect(() => {
        size = newWidth.value * param.height;
    });
    

    如果你已经熟悉了 Vue3 的用法,你会更习惯以下简洁的用法。

     let param = reactive({ width: 5, height: 2  });
            
    let newWidth = computed(() => {
        return param.width * 2
    });
    
    let size = computed(() => {
        return newWidth.value * param.height
    });
    
    

    它相对来说简洁优雅很多,只用 computed 包裹并赋值一次,用到的时候只要取 .value 即可。

    computed 实现

    function computed(getter) {
      let result = ref()  // 创建一个新的响应引用
    
      effect(() => (result.value = getter())) // 在 effect 调用时, 将 getter 的返回值赋值给 result.value ,
    
      return result // 返回引用
    }
    

    非常简洁。整体代码如下:

    const targetMap = new WeakMap();
    let activeEffect = null // The active effect running
    
    function track(target, key) {
        if (!activeEffect) return;
        let depsMap = targetMap.get(target);
        if (!depsMap) {
            targetMap.set(target, (depsMap = new Map()));
        }
        let dep = depsMap.get(key);
        if (!dep) {
            depsMap.set(key, (dep = new Set()));
        }
        dep.add(activeEffect);
    }
    function trigger(target, key) {
        const depsMap = targetMap.get(target);
        if (!depsMap) return;
        let dep = depsMap.get(key);
        if (dep) {
            dep.forEach(element => {
                element();
            });
        }
    }
    
    function reactive(target) {
        const handler = {
            get(target, key, receiver) {
                let result = Reflect.get(target, key, receiver);
                track(target, key);
                return result;
            },
            set(target, key, value, receiver) {
                let oldValue = target[key];
                let result = Reflect.set(target, key, value, receiver);
                if (result && oldValue != value) {
                    trigger(target, key);
                }
                return result;
            }
        }
        return new Proxy(target, handler);
    }
    
    function ref(raw) {
        const r = {
            get value() {
                track(r, 'value')
                return raw
            },
            set value(newVal) {
                raw = newVal
                trigger(r, 'value')
            },
        }
        return r
    }
    
    function effect(eff) {
        activeEffect = eff  // Set this as the activeEffect
        activeEffect()      // Run it
        activeEffect = null // Unset it
    }
    
    function computed(getter) {
        let result = ref()  // Create a new reactive reference
    
        effect(() => (result.value = getter())) // Set this value equal to the return value of the getter
    
        return result // return the reactive reference
    }
    
    let param = reactive({ width: 5, height: 2  });
    
    let newWidth = computed(() => {
        return param.width * 2
    });
    
    let size = computed(() => {
        return newWidth.value * param.height
    });
    
    

    再执行如下代码,将会 console 出预期的结果。

    
    console.log(`newWidth is ${newWidth.value}, size is ${size}`); // newWidth is 10, size is 20
    
    param.width = 6;
    
    console.log(`newWidth is ${newWidth.value}, size is ${size}`); // newWidth is 12, size is 24
    

    Vue3 源码小析

    我们已经建立了一个响应式的系统了(嗯,当然是非常弱鸡版本的……)。在 Vue 的真实版本中,是比这个复杂N倍的。我们可以简单列举一下Vue 源码中响应式实现相关的文件。

    主要目录在 github.com/vuejs/vue-n…。

    主要结构如下(截止2021年6月10日):

    Vue3 响应式原理探索Part 5 - computed values 的实现

    有兴趣的同学可以直接阅读源码。

    小结

    • computed 用法更简洁优雅
    • computed 的封装实现基于 refreactive 函数

    起源地下载网 » Vue3 响应式原理探索Part 5 - computed values 的实现

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元