目录
- 前言
- 一、总览「Vue3 组件运行机制」
- 二、Vue3 的组件运行机制
- 1、组件实例创建
- 2、初始化阶段
- 3、建立组件的响应式渲染 effect(核心)
- 4、首次渲染(挂载)
- 5、更新阶段
- 6、卸载阶段
- 三、Vue3 是怎么“管理复杂 UI”的?
- 1、第一阶段:组件被创建(初始化阶段)
- (1)、创建组件实例
- (2)、执行 setup()
- 2、第二阶段:建立组件的响应式渲染机制
- (1)、创建组件的“渲染副作用”
- 3、第三阶段:当数据变化时发生什么?
- (1)、响应式系统触发 trigger()
- (2)、调度器开始“批量更新”
- 4、第四阶段:patch 阶段如何管理“复杂 UI”?
- 5、整个 Vue3 组件运行机制全景图
前言
一、总览「Vue3 组件运行机制」
Vue3 组件运行机制
= Vue 组件的一生
= 一个组件从“创建”到“销毁”的整个生命周期里,内部是如何运作的
= Vue 如何把「状态变化」自动变成「界面变化」,并且高效地管理整个组件树的更新过程
= “更新 + 挂载 + 组件关系 + 调度策略 + 生命周期” 的整体体系
它包含的不只是“组件的更新流程”,而是一个完整的闭环:
创建组件实例 ↓ 初始化 props/slots ↓ 执行setup()↓ 建立响应式 effect(渲染副作用) ↓ 首次 render → patch(挂载) ↓ 响应式数据变化 ↓ 调度更新 ↓ 重新 render → patch(更新) ↓ 卸载组件(销毁)二、Vue3 的组件运行机制
Vue3 的组件运行机制指的是组件从创建、初始化、建立响应式渲染 effect、首次挂载、响应式更新到最终卸载的完整内部执行流程;而组件更新过程只是其中在响应式数据变化时触发的 render 和 patch 更新阶段。
- 组件实例创建
- 初始化阶段
- 建立组件的响应式渲染 effect(核心)
- 首次渲染(挂载)
- 更新阶段
- 卸载阶段
创建 → 初始化 → 建立 effect → 挂载 → 更新 → 卸载1、组件实例创建
当你写:
<MyComp msg="hello"/>Vue 内部会创建一个组件实例对象:
constinstance={type:MyComp,props:{},slots:{},setupState:{},subTree:null,isMounted:false,update:null}📌 这一步只是“建档案”,还没渲染。
2、初始化阶段
包括:
- 解析 props
- 解析 slots
- 执行 setup()
constsetupResult=setup(props,{slots,emit})如果 setup 返回函数:
return()=>h('div',count.value)那它就会被当成 render 函数。
3、建立组件的响应式渲染 effect(核心)
这是运行机制的关键:
instance.update=effect(componentUpdateFn)从这一刻开始:
- 组件变成了一个“响应式副作用”
只要 render 里用到的响应式数据变了,组件就会自动更新。
4、首次渲染(挂载)
effect 第一次执行时:
render()生成 VNode 树 ↓patch(null,vnode)↓ 创建真实DOM此时:
instance.isMounted=trueinstance.subTree=vnode组件正式出现在页面上。
5、更新阶段
当响应式数据变化:
count.value++触发:
trigger → 调度组件 update → render 新 vnode → patch 新旧 vnode → 更新DOM这就是组件更新过程 = effect → render → patch。
- 详情请看:Vue 组件的更新过程(编译系统 + 响应式系统 + 虚拟 DOM & Diff)
但注意,它只是整个运行机制的一部分。
6、卸载阶段
当组件被移除:
<MyComp v-if="show"/>show = false时:
unmount vnode ↓ 调用生命周期钩子 ↓ 停止组件 effect(stop) ↓ 移除 DOM组件生命周期结束。
三、Vue3 是怎么“管理复杂 UI”的?
回答这个问题需要我们从一个 Vue 组件的一生讲起。
大概分为 4 个阶段:
- 第一阶段:组件被创建(初始化阶段)
- 第二阶段:建立组件的响应式渲染机制
- 第三阶段:当数据变化时发生什么?
- 第四阶段:patch 阶段如何管理“复杂 UI”?
1、第一阶段:组件被创建(初始化阶段)
当你写下:
<MyComp:msg="text"/>Vue 在背后做的第一件事是:创建组件实例,并执行 setup()。
(1)、创建组件实例
源码里是:
createComponentInstance(vnode)实例本质是一个大对象:
instance={vnode,// 组件的虚拟节点type,// 组件本身props,slots,setupState,// setup 返回的数据render,// render 函数subTree,// 组件渲染出的 VNode 树isMounted:false}- VNode 是组件的“身份证”
- instance 是组件的“大脑”
(2)、执行 setup()
setupComponent(instance)做了三件关键事:
| 步骤 | 作用 |
|---|---|
| 初始化 props | 响应式 |
| 初始化 slots | 插槽 |
| 执行 setup() | 建立响应式数据 & 拿到 render |
如果你用 <script setup>,这里会被编译成 setup 函数。
2、第二阶段:建立组件的响应式渲染机制
这里进入 Vue3 的核心魔法。
(1)、创建组件的“渲染副作用”
setupRenderEffect(instance)内部核心代码(极度简化版):
instance.update=effect(functioncomponentEffect(){if(!instance.isMounted){// 首次挂载constsubTree=instance.render()patch(null,subTree)instance.subTree=subTree instance.isMounted=true}else{// 更新constnextTree=instance.render()patch(instance.subTree,nextTree)instance.subTree=nextTree}})这就是那句经典总结的来源:组件更新过程 = effect → render → patch
- 详情请看:Vue 组件的更新过程(编译系统 + 响应式系统 + 虚拟 DOM & Diff)
这里发生了什么?
| 环节 | 本质 |
|---|---|
effect() | 把组件变成一个响应式副作用 |
render() | 读取响应式数据 → 生成新的 VNode 树 |
patch() | Diff 新旧 VNode → 更新真实 DOM |
从此以后:
- 只要组件用到的响应式数据变了 → 这个 effect 就会重新执行 → 组件自动更新
3、第三阶段:当数据变化时发生什么?
比如:
state.count++(1)、响应式系统触发 trigger()
trigger(target,key)找到依赖这个数据的副作用:
dep.forEach(effect=>queueJob(effect))⚠️ 注意:
- 这里 不会立刻执行组件更新,而是放进调度队列。
(2)、调度器开始“批量更新”
flushJobs()Vue 会:
- 去重(一个组件多次修改只更新一次)
- 按父 → 子顺序更新
- 异步批量执行(nextTick)
于是执行:
instance.update()又回到:
render → patch4、第四阶段:patch 阶段如何管理“复杂 UI”?
复杂 UI = 组件树
例如:
App ├─ Header ├─ List │ ├─ Item │ ├─ Item │ └─ Item └─ FooterVue 并不是“整棵树重画”,而是:
patch 时递归更新
patch(n1,n2){if(组件)processComponent()if(元素)processElement()}如果是组件:
updateComponent(n1,n2){instance.next=n2 instance.update()// 触发子组件更新}如果是元素:
patchElement()→patchProps()→patchChildren()如果是列表:
- Vue 用Key + 最长递增子序列算法(LIS)
- 尽量复用节点
- 减少 DOM 移动
5、整个 Vue3 组件运行机制全景图
响应式数据改变 │ ▼trigger()│ ▼ 调度器 queueJob │ ▼ 执行组件 effect │ ▼render()生成新 VNode 树 │ ▼patch(oldVNode,newVNode)│ ┌────────┴────────┐ ▼ ▼ 更新DOM递归更新子组件所以“Vue3 组件运行机制”到底包含什么?
| 模块 | 作用 | 关键词 |
|---|---|---|
| 响应式系统 | 追踪数据依赖 | track / trigger |
| 副作用系统 | 组件变成响应式 effect | effect |
| 渲染系统 | 生成虚拟 DOM | render / h |
| Diff 系统 | 找到最小 DOM 变化 | patch |
| 调度系统 | 控制更新时机 | queueJob / nextTick |
| 组件系统 | 管理实例和树结构 | instance / vnode |
它们 共同构成 Vue 管理复杂 UI 的“操作系统”