最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 精简Vue3源码解析,实现一个mini版【Vue3】

    正文概述 掘金(Bug_Lucas)   2021-04-22   629

    在看这篇文章之前希望大家还是有一定的基础,能够了解Vue2的一些基础原理,了解Proxy代码的基础应用以及WeakMap,Map,Set这些数据结构的特性。如果对这些还不了解的同学建议先去补一下基础知识。

    如果你对vue3还不了解建议先去学习下vue3。

    vue3基础特性

    vue3+Ts实战

    声明: 本文中采用的方法名均为源码中的方法名,很多代码结构按照源码的结构来写的,目的就是在于希望能够对想看源码的同学做一些引导。

    如果代码中有些地方你不能一下子想明白的,先尝试去接受它,然后回过头来再去理解它。

    重中之重:对于本文的学习方式上希望大家一定要更着去手写代码,多做一些思考,看完之后我相信你一定会有所收获。

    如果有什么不对的地方也欢迎大家留言指正。

    响应式

    我们都知道vue2中是通过defineProperty实现对数据的拦截监听,而vue3中采用的Proxy,相较于defineProperty,即能监听数组,不需要进行嵌套,不用遍历每个属性,针对整个对象更加轻便。

    vue3通过reactive创建一个响应式对象,当对象被修改的时候,视图也会随着更新,对应的副作用函数也会执行(这个我们后面实现watchEffect的时候再分析)。这其中主要有两个过程:

    • 对数据进行监听并收集依赖
    • 更新视图(后话)

    reactive内部就是通过Proxy实现对数据的拦截监听。

    // v3.js
    
    // reactive 的实现
    function reactive(target){
        return createReactiveObject(
            target,
            mutableHandlers
        );
    }
    
    /**
     * 真正创建响应式对象的函数
     * @param {*} target 对象
     * @param {*} handler 处理程序
     */
    function createReactiveObject(target,handler){
        const proxy = new Proxy(target,handler);
        return proxy;
    }
    

    Proxy对数据的监听主要在handler中进行处理, handler是一个定义一个或多个陷阱的对象。接着我们实现一下mutableHandlers对象

    // v3.js
    
    const get = createGetter();
    function createGetter(){
        return function get(target,key,receiver){
            const res = Reflect.get(target, key, receiver);
            console.log('get执行了',key);
            return res;
        }
    }
    
    const set = createSetter();
    function createSetter(){
        return function set(target,key,value,receiver){
            const res = Reflect.set(target,key,value,receiver);
            console.log('set执行了',key);
            return res;
        }
    }
    
    // proxy的处理程序,是一个定义一个或多个陷阱的对象
    // 只处理简单的 get 和 set
    const mutableHandlers = {
        get,
        set
    }
    
    // reactive 的实现
    function reactive(target){
      return createReactiveObject(
        target,
        mutableHandlers
      );
    }
    
    /**
     * 真正创建响应式对象的函数
     * @param {*} target 对象
     * @param {*} handler 处理程序
     */
    function createReactiveObject(target,handler){
      const proxy = new Proxy(target,handler);
      return proxy;
    }
    

    这样我们就实现了一个简单的reactvie,能够对数据进行监听了。可以通过以下代码测试一下:

    // v3.js
    
    const testObj = reactive({ count:10 }})
    testObj.count
    testObj.count = 20
    
    // 通过node v3.js执行当前代码
    // get执行了 count
    // set执行了 count
    

    这只是实现了对简单对象的监听,如果对象复杂一点,就会存在问题,例如:

    // v3.js
    
    const testObj = reactive({ count:10, info: { name:'lucas' }})
    testObj.info.name
    testObj.info.name = 'viky'
    
    // 执行结果如下
    // get执行了 count
    // set执行了 count
    

    这样监听就失效了,没有监听到name属性,优化一下get方法,如果当值为对象的时候,我们应该递归监听:

    // v3.js
    
    const isObject = (target)=>{ return target !== null && typeof target === 'object'}
    function createGetter(){
        return function get(target,key,receiver){
            const res = Reflect.get(target, key, receiver);
            console.log('get执行了',key);
            if(isObject(res)){
                return reactive(res);
            }
            return res;
        }
    }
    

    到这里我们的reactive已经实现了对数据的监听。

    订阅

    接下来我们开始收集依赖,依旧是在get中进行处理,通过track函数进行依赖收集,在这之前先大致介绍一下vue3中用于存储依赖的数据结构。

    精简Vue3源码解析,实现一个mini版【Vue3】


    起源地下载网 » 精简Vue3源码解析,实现一个mini版【Vue3】

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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