今天,我开始记录一下自己对vue3的源码部分的理解,此源码解读是按照我本人自己的理解来对源码进行解读,如果有不恰当的地方,欢迎大家指出,希望可以一起探讨学习。(本人也是前端的菜鸟,太细致或者深入的理解自己还目前达不到,只能对vue3粗略的运行流程有一个大概的理解)
首先,对于vue3中,我们从cli创建了vue项目或者在script中引入vue,都需要有一个创建,即
在script中引入为:
而在cli项目中为:
从里面能看出都有createApp,他会返回了一个app对象,之后又调用了app对象中的mount方法,在源码中
我们首先进入runtime-dom/src/index.ts文件中可以看到createApp这个函数
我们可以看出来这里app是由调用了ensureRenderer().createApp()来进行返回的,然后最后又返回了app这个对象。
我们进入ensureRenderer()函数中可以看到
在这里,renderer是渲染器函数,如果存在就直接返回,如果没有的话,则调用createRenderer进行创建渲染器。对于首次编译运行代码时,是不存在render渲染器的,所以要进行创建,进入createRenderer()函数中
此时,又调用了baseCreateRenderer(options)函数,这个函数具体的实现方式在439行,结束在2417行,如下图所示
在结束的位置,我们可以看到此时返回了一个对象,对象中包含了createApp,所以,在最初我们用的createApp(App)其实是调用了createAppAPI这个方法,我们再进入这个方法中
我们看到这里其实return了一个createApp,这个函数里有rootComponent和rootProps两个参数,其中第一个为我们传进的App组件。并且,这里还定义了一个isMounted是来判断是否进行了挂在,初次进入时,是没有进行挂在的,所以等于false。
在这个createApp中,主要是定义了app对象并进行了返回,这个返回的app对象就返回给了runtime-dom/src/index.ts文件中createApp函数中的app对象,然后再返回就到了文章最开始app=Vue.createApp()这个app。
并且在上图中的定义app对象中,定义了很多方法,例如use,mixin,component,mount等等。
那么例如在vue2中所用的一些vue.use方法,其实就是对这里的use进行了调用,这个我们会以后在说。
这里有一个重要的方法就是mount,我们在最开始调用完Vue.createApp()后,就要执行app.mount(“#app”)。那么这个执行是如何的呢?
这里面先创建了vnode,然后调用了render,渲染完后将isMounted=true,这是一个标志,代表了挂载完成了,下一次可以通过这个来进行patch比较。但是对于我们传进的是#app,无法根据这个来找到节点,所以在runtime-dom/src/index.ts文件中createApp函数中,对mount方法进行了重写,如下图所示
在图中,normalizeContainer函数中其实就是调用了document.querySelector(“#app”)这个方法
然后又回到了真正的mount方法中进行了调用,之后运行render方法进行挂在,最终在浏览器上显示了我们所写的代码
如果上面源码说的有问题,希望大家提出宝贵意见,大家一起共同进步。