课程地址:【已完结】全网最详细Vue3源码解析!(一行行带你手写Vue3源码)
第五部分-:(对应课程的第29-32节)
第29节:《实现渲染的createRender方法》
1、通过createApp()方法得到一个对象app,打印出来观察:发现 app 是一个对象,这个对象上面有很多属性,其中,mount是用来挂载的,provide是用来提供数据的,use是用来使用插件的:
2、在自己的工程中,7.createApp.html 文件中,编写如下代码:
3、在 runtime-dom 文件夹的入口文件中来实现 createApp 方法,它返回一个 app 对象,这个app对象上有一个mount方法,mount方法接收一个container容器,在这个方法中先清空这个container容器中的原有内容:
将选择dom元素的方法替换为我们之前写好的方法:
将创建app对象的过程写成另一个方法 createRender ,它接收我们写好的操作 dom 的一系列方法——为什么要把这些操作dom的方法单独出去,并在这里作为参数传递进去?因为在不同的平台运行代码时,不同平台操作dom的方式是不同的,所以需要单独写,并通过传参的形式传入。
这个 createRender 方法返回一个对象,这个对象上有一个createApp属性,它是一个方法,它接收我们传递给外层的createApp 方法的两个参数,即 rootComponent 和 rootProps ,返回一个app对象,这个对象上有一个mount方法。这里的createRender 方法相当于一个高阶函数。
定义 createRender 方法:
第30节:《创建虚拟dom》
1、将 createRender 方法剪切,放到 runtime-core/src 下新建的 render.ts 文件(源码中是renderer.ts文件)中并暴露出去:
2、在 runtime-core/src 下的入口文件index.ts 中引入 createRender 并暴露出去:
3、在 runtime-dom/src 下的入口文件index.ts 中引入 createRender 之前,由于我们之前配置的npm run dev 打包是只打包 runtime-dom 包,所以需要运行 npm run build 将所有的包都打包一下。然后运行 yarn install 重新安装一下,完成之后 node_modules 下的 @vue 下才会有 runtime-core 这个包:
4、在 runtime-dom/src 下的入口文件index.ts 中引入 createRender :
5、在render.ts 文件中添加如下代码:
6、在 runtime-core/src 下新建 apiCreateApp.ts 文件,将 render.ts 中的 createApp方法抽离到apiCreateApp.ts 文件中并暴露:
7、为了使 apiCreateApp.ts 文件中的createApp方法能够使用 render.ts 中的 render 函数,在render.ts中引入 apiCreateApp.ts 中暴露的 apiCreateApp 方法,并传递 render :
8、apiCreateApp.ts 文件中,这个方法主要是用来创建虚拟dom 也就是 vnode 的:
9、添加如下代码:
10、新建 vnode.ts 文件:
打印出来的参数就是在这里传进去的两个参数:组件和数据
10、由于创建虚拟dom有两种方式,一种是通过这个createVnode方法,一种是通过h函数,通过h函数最终也是会走createVnode方法,为了兼容两种方法的传参,将createVnode的方法入参改为如下,同时在方法内部进行区别是组件还是元素(通过createVnode方法传递进来的第一个参数,就是如上张截图中的第一个参数,也就是一个组件;而通过h函数传递的第一个参数,会是一个节点名称,如’div’):
使用 shapeFlag 字段标识是组件还是元素,并创建 vnode 对象:
第32节:《区分是组件还是元素》
1、查看源码工程中 shared下的 shapeFlags 枚举值,是用位表示的:
2、来到我们自己的工程,shared/src下新建 shapeFlag.ts 文件(源码中为shapeFlags.ts ),将源码中该文件的内容复制过来,并在shared的入口文件中导入并全部暴露:
3、在 vnode.ts 中添加代码:
4、继续添加如下代码:
(这里的位运算以及位运算符 & 与 | 不太懂,待补充相关知识 )
5、测试打印vnode:
第32节:《总结知识点》
基本就是前两节的一个总结