Vue挂载本质是将实例转为真实DOM并插入页面的过程,涵盖响应式初始化、VNode生成与patch、生命周期联动:先响应化data并触发beforeCreate/created;再编译template为render函数,触发beforeMount;接着通过渲染Watcher生成VNode并patch到DOM,触发mounted;后续更新则基于响应式依赖触发diff高效重渲染。

Vue挂载过程,本质是把一个 Vue 实例(或组件)从 JavaScript 对象变成真实 DOM 并插入页面的过程。它不是简单地“把模板塞进 HTML”,而是贯穿响应式系统、虚拟 DOM 构建与打补丁、生命周期钩子联动的一整套机制。
初始化阶段:数据响应化与配置就绪
执行 new Vue(options) 后,Vue 调用内部 _init 方法完成初始化:
- 合并用户传入的 options(data、methods、computed、watch 等),规范选项结构
- 初始化事件系统($on/$emit)、生命周期状态标志(如 _isMounted)
- 对 data 执行响应式转换:Vue 2 用 Object.defineProperty 劫持属性,Vue 3 用 Proxy,建立依赖收集和派发更新能力
- 初始化计算属性、侦听器、指令等逻辑
此时 $el 为 null,真实 DOM 尚未接触,beforeCreate 和 created 钩子依次触发。你可以操作 data 和 methods,但无法访问 DOM。
$mount 阶段:准备渲染函数与 VNode 入口
调用 vm.$mount(el)(或自动挂载)后,Vue 开始进入视图层处理:
立即学习“前端免费学习笔记(深入)”;
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 若传入 el,先缓存原 DOM 节点;若未传,等待后续手动挂载
- 若没有显式提供 render 函数,但存在 template 或 el 内的 HTML,则调用编译器(compiler)将其编译为可执行的 render 函数
- 最终确保实例拥有一个返回 VNode 的 render(),这是后续所有渲染的源头
这一步完成后,beforeMount 钩子被调用。此时 $el 仍是旧的(或 null),VNode 还没生成,但 render 函数已就绪。
首次渲染:VNode → 真实 DOM
mountComponent 是核心入口,它启动真正的挂载循环:
- 创建一个专属的 渲染 Watcher,负责监听响应式数据变化,并在变化时重新执行 render()
- 首次调用 render(),生成一棵完整的初始 VNode 树(含组件、插槽、指令等抽象节点)
- 调用 patch()(也称 __patch__),将 VNode 树“打补丁”到目标容器上:
→ 若是首次挂载(空容器),递归调用 createElm 创建真实 DOM 元素
→ 遇到组件节点,触发子组件初始化与挂载(递归)
→ 指令(如 v-model)激活、子组件 mounted 钩子同步触发
当 patch 完成,真实 DOM 插入文档流,mounted 钩子被调用,$el 正式可用,组件进入可交互状态。
后续更新:响应式驱动的差异更新
挂载完成后,数据变化不再重绘整个界面,而是走高效更新路径:
- 响应式 setter 触发依赖通知,唤醒渲染 Watcher
- Watcher 重新执行 render(),生成新的 VNode 树
- 新旧 VNode 树通过 diff 算法 比对,找出最小变更集(如文本变化、属性更新、节点增删)
- 仅将差异部分应用到真实 DOM,跳过未变动区域
这个过程对应 beforeUpdate → updated 钩子。它让 Vue 在保持声明式写法的同时,获得接近手动 DOM 操作的性能。

















