从0看vue3 源码 记录

1  vue3 源码地址 https://github.com/vuejs/vue-next.git  跳转

2  看了很多文章   把了解到的知识点  做个总结

    a.如果你要开发一个要发布的框架组件 也就是package 建议使用  lerna,   给你个链接  不懂也不影响v3

    b.clone下v3项目后 如何运行起来  https://juejin.im/post/5d9c99a0f265da5b8f10762c  按照这个步骤  修改 +创建html 即可  不过         记得要npm run dev 或者build一下 v3 才有dist哦(不过运行起来 貌似没啥用 只不过是装个b 跑起来了而已 哈哈)

    c.看了很多文章 主要总结核心是 v3核心文件在 packages文件夹里 其中reactivity 是最帅的数据监听部分 也是 很多想看源码的人关注的地方,之前v2面试总问 v2是如何实现数据监听的 Object.defineProperty  那么v3 是怎么实现的呢 所以从这里开始即可(这里如果你还不知道v2是如何实现的,那么去这里,第一篇第二篇,看完 这2个对你理解v3的数据监听会有很大帮助,读第二篇的时候,又去补充了一下js队列的相关知识,链接 这里,从这里你能理解microtasks 和 macrotasks的关系)

    d.进入正题,查看v3 核心目录 数据监听

    e.楼主是跟着 这篇文章走的 链接 讲的真的很好 主要是带你看懂v3核心部分(当然是看了2遍后更加感悟的。)

    不过我推荐先看这个 链接 主要是因为这部分 我们主要讨论数据监听   我们按着上面我推荐的文章开始学习

    f.当你看了这篇文件第一大段的时候  我相信 你已经了解 v3核心的数据监听 是new proxy 进行对象代理  那么你内心一定想问 这和v2 的 Object.defineProperty 有什么区别呢 或者 你还不知道  proxy 是个什么东西?

   g. 那我推荐 这个文章 链接  这里讲了 proxy 是如何进行代理的 以及最重要的 或者以后面试人员可能会问的痛点   v2 v3 代理的区别 我简单总结2点   1 )Object.defineProperty 存在缺陷 无法监听数组(这也是v2项目为什么声明变量的时候尽量减少使用数组的关系) 2) proxy 属于es6 多了很多全新的实用的api 将v2中用繁琐代码实现的功能 一个api搞定 (就例如监听数组)

  h.看完 g的推荐后 我们接着 f里我推荐的文章 再次放个链接  此时你应该已经看到了

  第二部分 第一痛点 Proxy API 的一些细节  这里我主要强调一下  你一定要理解的东西  这样 如果没达到 就反复再去看  

  第一,proxy是如何监听数组的  也就是 当他代理数组了 那么当我给数组添加值后 set 后一定要返回true 否则报错  这是api级别要注意的。

  第二,无论是get 还是set 其实我们简单理解就是给对象赋值 或者 塞值 但最后 选择使用了 Reflect.get(target, key, receiver)  和        Reflect.set(target, key, value, receiver)  此时 你需要理解 Reflect 是什么 和  Reflect 的特点    链接拿走   把里面介绍的api 都敲一    遍 

  i. 第二痛点 多次的set/get  这里我主要强调一下 

  第一,数组set  先试set 最大索引的值 然后重新 set 数组length的长度

  j. 第三痛点 proxy只代理一层  这里我主要强调一下

  第一,proxy相对v2的defineproprety 可以监听数组了  但是对于多层次结构 还是无法做到的 

 k. 针对上面的3痛点  文章给出了解决方案  这里大家只需要 理解思路即可 不必过多纠结  v3里处理的 相对会更巧妙

 l.文章最后简述了 v3 处理的方法  在这里 我建议了解即可 因为 我在这也花了部分时间 但是 其实 还是应该在v3源码里去理解更好些  主要看懂了 也 串联不上  适合二次阅读 当然 文章是真的好

 m. 此时我们回到e 的 第一个链接  开始学习v3 代码

到这里 数据侦测 如果你学会了 那么你应该 也可以写一个简单的demo了  这里 我也是 自己仿造了一个   注意 此时一定要能独立完成 这个数据监测  当然 我这个例子 回显数据的时候 也没有太完整 只是 一个简例  不必过多纠结

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id = 'gq'></div>
    name:<input type="text" oninput="changeInput(this,'name')">
    age:<input type="text" oninput="changeInput(this,'age')">
</body>
<script>
    const tip = (v) => document.querySelector('#gq').innerHTML = `值是${JSON.stringify(v)}`
    const isObject = (val) => val != null && typeof val == 'object'
    function gqProxy(t) {
        return new Proxy(t,{
            get(target, p, value) {
                const res = Reflect.get(target,p,value)
                // 如果返回的是对象 则需要递归代理
                if(isObject(res)){
                   return  gqProxy(res)
                }
                return res
            },
            set(target, p, value, receiver) {
                const set2 = Reflect.set(target,p,value)
                tip(receiver)
                return true
            }
        })
    }
    let t1 = {
        name:'gq',
        age:[18,19]
    }
    let t1_proxy = gqProxy(t1)
    tip(t1)
    const changeInput = (e,param) => isObject(t1_proxy[param]) ? t1_proxy[param].push(e.value): t1_proxy[param] = e.value
</script>
</html>

  n.完成上述 后 我们开始阅读 v3  reactive.ts里的代码   此时 如果你的es6语法不是很了解  那么看起来会有些吃力   这里给你一个链接  遇到问题 可以对照理解   读 reactive的时候  在文章里 的 秘径追踪 里 跟着MARK 去理解 

  o.  从 reactive  开始 到  createReactiveObject    搜的第一个点 weakmap  这是es6 里的一个map集合  相关的 weakset等  那么我们就该去了解一下  是如何使用的 而且优点在哪  weakmap 存储的特点是什么   

这里 你了解后 会涉及到 js 的 垃圾回收机制  那么可以去学习一下 node.js 的垃圾回收机制  自己去 试一试   这里提供一些 手动测试js 垃圾回收机制的指令

  1. node --expose-gc

    • 参数 --expose-gc 表示允许手动执行垃圾回收机制。
  2. global.gc() 手动执行一次垃圾回收

  3. process.memoryUsage() 查看内存占用状态 heapUsed 内存占用

    • process.memoryUsage() 方法返回Node.js进程的内存使用情况的对象,该对象每个属性值的单位为字节。

    • heapTotal和 heapUsed 代表V8的内存使用情况。 external代表V8管理的,绑定到Javascript的C++对象的内存使用情况。 rss, 驻留集大小, 是给这个进程分配了多少物理内存(占总分配内存的一部分) 这些物理内存中包含堆,栈,和代码段。对象,字符串,闭包等存于堆内存。 变量存于栈内存。 实际的JavaScript源代码存于代码段内存。

 p.看代码的时候 由于抽离的方法比较多  这里 给个链接 这个文章里  将部分方法 做了单独解释  有助于你理解 reactive文件

 q.读到  reactive 里的 createReactiveObject 最后的时候

这里的 target 上面只是过了很多验证 当然 都是优化  handlers 是我们监听后的 set 和get 处理  所以 此时转头进入 baseHandlers

这里将 set 和get方法 进行了单独书写 我们先读get 再set即可   这里大量的 对Symbol 进行了使用  给个链接  认真学一下

r. 学习的过程 会涉及很多es6的语法  比如 参数的?  比如 方法返回类型  是  v is Ref  里面还有大量的三目   还有 %check的 谓词函数  都需要大家一点一点去查询了解

这里就是 上文提到的 深度监测  利用递归   看完  get   再看set

这里红线   的  2个判断 是尤大 比较巧妙的地方   数组 push  触发  索引添加 和  length变化 2次set  这里如果你能理解 就真的懂了

s. 读完 set get 后  数据监听部分 其实 你就读完了  不知道你有多大收获  其实目前 你应该了解了 下面的文件

剩下的楼主也在探索

备注  还有3篇好的文章   楼主并没有想好  放在哪个阶段  但先把链接挂着   等楼主学完  会 放到 适合初学者看的位置

https://juejin.im/post/5d977f47e51d4578453274b3

https://juejin.im/post/5d9c41436fb9a04def4e5b1c#heading-6

https://juejin.im/post/5d9c9a135188252e097569bd

====================================================================================

ts中的 Record   推荐这个文章  https://www.leevii.com/2018/10/record-in-typescript.html

发布了100 篇原创文章 · 获赞 75 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/gaoqiang1112/article/details/102619184