当前位置: 首页 > news >正文

Vue3 组件挂载流程(源码解读)

1. 入口:createApp 创建应用实例

挂载的起点是 createApp 函数,它创建一个应用实例(App),并关联根组件。

// packages/runtime-dom/src/index.ts
export function createApp(rootComponent, rootProps = null) {// 创建应用实例(包含全局配置、组件、指令等)const app = {_component: rootComponent, // 根组件_props: rootProps,_container: null,// 挂载方法mount(container) {this._container = container;// 核心:创建根组件的虚拟 DOM 并渲染render(h(this._component, this._props), container);}};return app;
}
  • createApp 接收根组件和 props,返回一个含 mount 方法的应用实例。
  • mount 方法是挂载的入口,它调用 render 函数将根组件渲染到容器(DOM 元素)。
2. 核心渲染:render 函数

render 函数负责将虚拟 DOM(VNode)转换为真实 DOM 并插入容器。

// packages/runtime-core/src/renderer.ts
function render(vnode, container) {if (vnode == null) {// 卸载逻辑(略)} else {// 核心:执行补丁算法,对比新旧 VNode 并更新 DOMpatch(container._vnode || null, vnode, container);}// 缓存当前 VNode 用于下次更新container._vnode = vnode;
}
  • render 接收虚拟 DOM(vnode)和容器(container)。
  • 首次渲染时,container._vnode 为 null,直接执行 patch 初始化 DOM。
3. 补丁算法:patch 处理组件挂载

patch 是虚拟 DOM 的核心算法,根据 VNode 类型执行不同操作(元素 / 组件 / 文本等)。对于组件,会触发初始化流程。

// packages/runtime-core/src/renderer.ts
function patch(n1, n2, container) {if (n1 === n2) return;if (n2.type === Fragment) {// 处理 Fragment(略)} else if (typeof n2.type === 'object') {// 组件类型 VNode:执行组件挂载processComponent(n1, n2, container);} else if (typeof n2.type === 'string') {// 普通元素(略)}// 其他类型(文本、注释等,略)
}
  • 当 VNode 的 type 是对象(组件选项)时,调用 processComponent 处理组件。
4. 组件初始化:processComponent

processComponent 区分首次挂载和更新,首次挂载时会创建组件实例并初始化。

// packages/runtime-core/src/renderer.ts
function processComponent(n1, n2, container) {if (n1 == null) {// 首次挂载:创建组件实例并挂载mountComponent(n2, container);} else {// 更新组件(略)}
}
5. 组件实例化与挂载:mountComponent

mountComponent 是组件挂载的核心,负责创建组件实例、初始化生命周期、执行渲染等。

// packages/runtime-core/src/renderer.ts
function mountComponent(vnode, container) {// 1. 创建组件实例const instance = createComponentInstance(vnode);// 2. 初始化组件(处理 props、slots、设置上下文等)setupComponent(instance);// 3. 设置组件渲染Effect(响应式触发更新)setupRenderEffect(instance, container);
}
5.1 创建组件实例:createComponentInstance
// packages/runtime-core/src/component.ts
function createComponentInstance(vnode) {const instance = {vnode, // 组件对应的 VNodetype: vnode.type, // 组件选项(如 { setup, render })props: {}, // 接收的 propsslots: {}, // 插槽ctx: {}, // 组件上下文isMounted: false, // 是否已挂载// 其他生命周期状态...};return instance;
}
  • 实例包含组件的核心信息:VNode、props、插槽、上下文等。
5.2 初始化组件:setupComponent

处理 props、slots,并执行 setup 函数(若有)。

// packages/runtime-core/src/component.ts
function setupComponent(instance) {// 1. 解析 props 和 slotsconst { props, slots } = instance.vnode;instance.props = resolveProps(instance.type.props, props); // 解析 propsinstance.slots = resolveSlots(slots); // 解析插槽// 2. 执行 setup 函数const setupResult = instance.type.setup?.(instance.props, {slots: instance.slots,emit: (event, ...args) => { /* 处理事件发射 */ }});// 3. 处理 setup 返回值(函数或对象)if (typeof setupResult === 'function') {instance.render = setupResult; // setup 返回渲染函数} else if (isObject(setupResult)) {instance.setupState = setupResult; // 暴露给模板的响应式数据}// 4. 若组件无 render 函数,自动编译模板生成(需编译器支持)if (!instance.render) {instance.render = compileTemplate(instance.type.template);}
}
  • setup 函数的返回值会被处理为组件的渲染函数或响应式状态。
  • 若组件未定义 render,则通过编译器将 template 转换为 render 函数(运行时 + 编译器版本支持)。
5.3 设置渲染 Effect:setupRenderEffect

创建响应式 Effect,关联组件渲染逻辑,实现数据变化自动更新。

// packages/runtime-core/src/renderer.ts
function setupRenderEffect(instance, container) {// 创建 Effect:依赖收集+触发更新instance.effect = effect(() => {if (!instance.isMounted) {// 首次渲染:执行 render 生成子 VNodeconst subTree = instance.render.call(instance.ctx);instance.subTree = subTree;// 递归 patch 子 VNode(渲染组件内容到 DOM)patch(null, subTree, container);instance.isMounted = true; // 标记为已挂载} else {// 更新逻辑(略)}},{ scheduler: queueJob } // 调度器:控制更新时机);
}
  • effect 是 Vue3 响应式系统的核心,首次执行时会:
    1. 调用组件的 render 函数生成子虚拟 DOM(subTree)。
    2. 递归执行 patch 处理 subTree,将其转换为真实 DOM 并插入容器。
    3. 标记组件为已挂载(isMounted = true)。
  • 当组件依赖的数据变化时,effect 会重新执行,触发更新逻辑。
6. 最终:真实 DOM 插入容器

patch 递归处理子 VNode 时,会将组件的模板内容(如 <div>{{ msg }}</div>)转换为真实 DOM 节点,并插入到挂载容器中,完成整个组件的挂载。

总结:挂载核心流程

  1. createApp 创建应用实例,关联根组件。
  2. 调用 app.mount(container) 触发渲染。
  3. render 函数调用 patch 处理根组件 VNode。
  4. patch 识别组件类型,调用 processComponent
  5. mountComponent 完成:
    • 创建组件实例(createComponentInstance)。
    • 初始化 props、slots、执行 setupsetupComponent)。
    • 创建渲染 Effect,执行 render 生成子 VNode 并递归渲染为真实 DOM(setupRenderEffect)。

整个过程通过虚拟 DOM 桥接组件逻辑与 DOM 操作,结合响应式系统实现数据驱动视图。

http://www.dtcms.com/a/530037.html

相关文章:

  • 老榕树建站软件wordpress 站点网络
  • 岗巴网站建设优秀企业网站模板下载
  • 自己动手建设网站国家企业信用网官网
  • 呼市网站制作大连网站关键词
  • wordpress搜索页分类怎样建设的网站好优化好排名
  • Java的注解
  • 专业公司网站 南通免费素材库大全
  • 哪家网站设计公司好出货入货库存的软件
  • 做淘宝客可以有高佣金的网站宣传册设计一般多少钱
  • 网站logo图怎么做如何加强网站安全建设
  • [linux] windows如何快乐部署LLM:linux子系统—wsl
  • 单片机开发---分层架构设计
  • 响应式网站建设福州网页版微信二维码扫描
  • 山东港基建设集团网站wordpress双主题缓存
  • 岳阳企业网站定制开发wordpress 4.8.2 漏洞
  • BELLE-A论文翻译
  • (三)Gradle 依赖版本控制
  • 汕头网站建设工作做一个电子商务网站建设策划书
  • 【Java 反射机制】
  • 2016年网站设计风格山西seo网站设计
  • 局域网建设网站视频教程网站制作都包括什么
  • 网站建设工作推进会上的讲话在电商网站上做推广的技巧
  • 公司做网络推广哪个网站好网络推广专员好做吗
  • 最优传输理论学习(1)+PINN文献阅读
  • 网站关键词几个好wordpress 徽标
  • 培训网站项目ppt怎么做东莞网站优化案例
  • 如何建团购网站网站建设推广襄樊
  • C++数据结构【顺序表和Vector】
  • mujoco 仿真导纳控制律
  • 做引流去那些网站好网站挖掘工具