发布于

Vue3应用初始化到首次渲染

Authors
  • avatar
    Name
    田中原
    Twitter

Vue3应用初始化到首次渲染

目录

应用程序初始化

packages/runtime-dom/src/index.tscreateApp 方法

主要做三件事

  1. 创建app对象:延迟创建渲染器对象 ensureRenderer
  2. 重写mount方法:
    1. 重写mount方法,因为createApp是runtime-dom中针对浏览器平台实现的。而runtime-core/src/apiCreateApp.ts文件中createApp方法中的app.mount 是支持跨平台
    2. 兼容Vuejs2.x写法
  3. 调用mount挂载

创建app对象

延迟创建渲染器对象 ensureRenderer

延迟创建渲染器对象,这样可以使核心渲染器逻辑在用户只从Vue中导入响应式工具时可以被tree-shaking。

渲染器具体实现 baseCreateRender

通过packages/runtime-core/src/renderer.tscreateRenderer 调用

render函数,以及渲染用的一系列方法

主要创建了渲染操作相关的一系列的函数,最后返回render函数,作为渲染时调用

函数名功能描述
patch根据不同的 vnode 类型执行不同的逻辑
processText处理文本节点
processCommentNode处理注释节点
mountStaticNode挂载静态节点
patchStaticNode更新静态节点
moveStaticNode移动静态节点
removeStaticNode移除静态节点
processElement挂载元素。只针对组件类型的 vnode
mountElement挂载元素。只针对组件类型的 vnode
setScopeId设置 scopeId
patchElement更新元素。只针对组件类型的 vnode
patchProps更新 props
processFragment挂载片段
mountChildren挂载子节点,深度优先递归调用 path
patchChildren更新子节点
patchBlockChildren更新块子节点
move移动节点
next获取下一个节点
unmount卸载节点
remove移除节点
unmountChildren卸载子节点
processTextOrComment处理文本或注释节点
setupRenderEffect设置渲染 effect
queuePostRenderEffect队列渲染 effect

创建app对象,从app层面添加全局方法createAppAPI

packages/runtime-core/src/apiCreateApp.tscreateAppAPI

  1. 创建app对象
  2. 为app对象添加usemixincomponentdirectivemountunmountproviderunWithContext方法
  3. 返回app对象

createApp 创建时会将app组件对象作为根组件传入

📌app创建过程通过闭包和函数柯理化实现了参数保留 如:执行app.mount,不需要传入render,因为在createAppApi时渲染器render参数已保留

初始化为什么要重写app.mount

  1. 兼容Vuejs2.x写法
  2. 使用API时更灵活

runtime-dom/src/index.ts文件中createApp中重写app.mount

runtime-core/src/apiCreateApp.ts文件中createApp方法中的app.mount 是支持跨平台:

  1. 先创建vnode再渲染vnode
  2. 参数rootContainer可根据不同渲染平台不同

渲染核心流程

创建vnode和渲染vnode。

渲染逻辑入口

packages/runtime-core/src/renderer.ts 文件baseCreateRenderer 中定义的render 函数

patch具体实现

packages/runtime-core/src/renderer.ts 文件baseCreateRenderer 中定义的patch 函数。

调用baseCreateRenderer 中各种的方法,主要实现vnode到dom的挂载

  1. 判断是否第一次挂载,是否有变动。(n1==null)时表示首次挂载
  2. 根据vnode节点类型调用不同的处理逻辑: 文本节点、注释节点、静态节点、Fragment、元素、组件、teleport、suspense、无效vnode类型
  3. 节点处理完成后根据需要设置ref

组件处理processComponent

通过节点类型调用processComponent,判断是挂载还是更新或者是keepLive组件activate

组件挂载mountComponent

如果是首次挂载调用packages/runtime-core/src/renderer.ts 文件baseCreateRenderer 中定义的mountComponent 函数

组件vnode会比元素vnod多组件的配置componentOptionscomponentInstance 组件的实例

挂载组件:

  1. 创建组件实例,通过对象的方式创建当前渲染的组件的实例。
  2. 判断是不是keepAlive组件,是的话注入renderer
  3. 设置组件实例,保留组件相关数据,维护组件上下文,对props、插槽、以及其他实例的属性的初始化处理
  4. 设置并运行带副作用的渲染函数 setupRenderEffect

元素挂载mountElement

packages/runtime-core/src/renderer.tsprocessElement 判断完n1 == null 是首次渲染时调用mountElement

mountElement 的主要处理逻辑:

  1. 根据不同平台创建元素、处理其他类型节点和递归处理子节点
  2. 调用created生命周期
  3. 设置scopeId、处理props、调用vnodeHook
  4. 调用beforeMount生命周期
  5. 插入到dom
  6. 调用mounted 生命周期