VUE3源码阅读笔记----初始化流程

905 阅读5分钟

vue3正式版发布已有不少时间了,一直没有机会去使用,这周用了vue3写了一点页面,对vue3的源码产生了好奇,所以趁着周六来学习一波vue3的源码。这里就不讲vue3的相关写法了,只关注它的源码。

vue架构

上图是vue代码的一个架构,主要是三个模块。主要是程序运行时有关的模块、响应式模块、程序编译相关的模块。今天因为是学习初始化流程,就先从runtime-dom开始说起吧。

createApp

我们知道vue3初始化项目不是new Vue了,而是使用createApp().mount()这样的方式,所以要了解初始化流程必然得先去找到createApp这个函数在哪。

这个函数在runtime-dom模块下src/index.ts里

其中app就是那个应用程序的实例,他是由ensureRenderer这个方法创建的,他有个mount方法可以给我们使用。

所以又要去看ensureRenderer这个方法

其中renderer是个单例,这个ensureRenderer方法会看这个renderer有没有创建,如果创建直接返回,没有的话就调用createRenderer这个方法去创建renderer。这个renderer就是实例真正的创建者。所以又要去看createRenderer这个方法了。

好吧,有点绕,又要去baseCreateRenderer这个方法去看。

(去看了下baseCreateRenderer这个方法,竟然有1800行,这里就不贴过来了。)

这个方法是个工厂函数,就关注下它return了个啥吧。

所以createAppApi才是应用程序创建的地方啊。

这里面有个app就是那个应用程序实例,是个对象里面有些属性。里面有些熟悉的面孔,比如use,mixin,component,directive。这里就体现了跟vue2的区别。

  1. 之前vue2都是静态方法,容易被全局配置给污染,现在实例方法就不会了。
  2. vue2没用的一些方法也会打包进去,vue3就不会了。
  3. 逻辑上来说创建了一个实例去调用实例里的方法是符合逻辑的。还可以链式调用。

这里我们关注下mount这个方法

这里不难发现,需要看这个render函数,他是把虚拟dom转变为真实dom的操作。这个render方法是createAppAPI这个方法的参数,所以又要回去找render方法了

这里不难发现,关键是patch方法,当我们没挂载过时第一个参数会传null,再传我们的vnode和container进去

这个方法判断了我们传进去的类型。那我怎么判断我初始化它会走哪个类型呢。根据我在浏览器上的调试,它判断我们传进来的是component。所以就跟着流程走下去,后面的代码又比较绕,直接看后面关键的代码吧,setupRenderEffect这个方法。

这里我没有把所有的代码都贴过来,就两个地方。先计算出当前dom树对应的vnode,然后传进patch函数,这个patch函数就是转换虚拟dom的函数,这回就先不看了吧,下回再看。

以上其实就是vue3初始化的流程。看完一个字感觉就是绕,绕来绕去的,但是在里面认真看的时候又感觉到了逻辑的缜密,只能说尤雨溪牛逼。

手写个简版的初始化流程

看是看完了,也感觉到了牛逼,那怎么学会它呢,就得自己模仿着写个简易版出来

下面就开始手写吧。首先第一步肯定是创建个html文件,并模仿个vue初始化的流程来创建个vue实例。

第一步工作,我们需要个vue,里面有个createApp方法,这个方法根据看的源码其实就是返回renderer这个实例里的createApp方法

第二步当然是声明这个renderer啦

这里可以发现,其实它不止可以操作dom,它可以干任何事,取决于你传啥进去。其实可以自定义操作的,比如画canvas啥的

第三步是定义createRenderer函数

第四步,定义createAppApi方法

所以,整体的一个结构已经出来了

这就是vue3初始化的一个大概流程,还是比较清晰的。

在createApp方法内真正创建app的是renderer。然后renderer是由createRenderer这个方法创建的。它返回了一个render和createApp。这个createApp呢又是createAppApi这个方法创建的。这个方法接受到render之后,创建一个app,定义mount方法。mount将来会调用render函数。将vnode转换为真实dom。根据这个思路就来完成我们的简易初始化方法吧。

这就是我的简易方法,其实就是解析vnode,展示在页面上而已。我们来验证一下

这里可以看的我们的vnode已经添加在页面上啦。我的简易vue初始化流程就已经完成了。

总结

其实看源码比如我这回看初始化流程的源码就要先看他是怎么使用的。比如vue3初始化是createApp这个方法,那就去源码里找createAPP方法,然后一步一步走下来。虽然事后去回味就感觉挺绕的,但是在我看的时候完全没有这样的感觉。看完后其实马上就会忘记的,所以趁热打铁自己实现一个简易版出来。可以巩固一下源码的思路,不至于这么快就忘记。

今天完成了vue3初始化流程的学习,感觉不是很难就是有点绕而已,下回继续学习vue3的核心部分,响应式!

(ps: 掘金这个代码块是怎么用啊,我从vscode复制过来的代码怎么发布完就显示成一行的了,搞得我都换成图片了,有没有大佬教一下。)