vue渲染流程为template→编译render函数→mount启动→响应式触发重新render→patch差异更新;包含parse/transform/generate三阶段编译、createapp-mount链路、reactivity与renderer协同及手动控制patch机制。

Vue 的渲染流程不是黑箱,而是一条清晰可追踪的链路:从你写的 template 开始,经过编译、挂载、响应式绑定、虚拟 DOM 生成,再到真实 DOM 更新。掌握这条路径,能快速定位性能卡点、理解响应式失效原因,甚至手写简易渲染器。
Template 编译:把字符串变成可执行的 render 函数
Vue 在非运行时构建(如 Vue CLI)中,会提前把 template 编译为 render 函数;在浏览器中直接用 runtime-only 版本时,则依赖 vue/compiler-dom 运行时编译。核心产出是一个返回 VNode 的函数,例如:
template:→ 编译后生成类似:
render() { return h('div', { id: 'app' }, this.msg) }这个过程包含三步:parse(转成 AST)、transform(应用插件如 v-model、v-if 转换)、generate(生成 JS 字符串)。开发中可通过 vue/compiler-dom.compile() 手动触发编译,调试时打印 AST 查看结构是否符合预期。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
Mount 启动:createApp → mount → 触发首次 render
调用 app.mount('#app') 后,Vue 创建根组件实例,初始化 props、slots、setup(),然后执行 render 函数得到首帧虚拟 DOM 树。此时尚未操作真实 DOM —— 它只是一组描述节点的 JavaScript 对象(VNode)。关键点:
- mount 不等于“立刻插入 DOM”,而是启动响应式系统 + 首次 patch 的入口
- 如果组件有 setup() 返回函数或 defineComponent 写法,render 会在 effect 作用域内执行,确保响应式依赖被收集
- 根组件的 el 会被缓存,后续 patch 均基于该容器进行比对和更新
Reactivity + Renderer 协同:数据变 → effect 触发 → render 重执行 → patch 差异更新
响应式系统(reactivity 包)与渲染器(renderer 包)解耦但强协作。当你修改 ref 或 reactive 数据时:
- trigger 操作通知所有依赖该属性的 effect(包括组件 render effect)
- render effect 重新执行,生成新的 VNode 树
- Vue 调用 patch(oldVNode, newVNode),递归比对两棵树,仅对有差异的节点执行 DOM 操作(add、remove、setAttr、textContent 等)
patch 是细粒度更新的核心——它不全量替换,也不依赖脏检查,而是靠 VNode 的 key、type、props 和 children 结构做最小化变更。
手动控制 patch:$forceUpdate 与 shouldUpdate 的边界
绝大多数场景无需干预 patch,但两种情况需注意:
- $forceUpdate() 强制触发当前组件 render,跳过依赖追踪。仅在响应式系统未覆盖的场景使用(如直接修改数组索引 arr[0] = x 且未用 Vue.set),但应优先改用 push/splice/ref.value = ... 等响应式方式
- 自定义 shouldUpdate(通过 defineComponent({ shouldUpdate }))可拦截 diff,返回 false 则跳过该组件及其子树的 patch。适合静态内容或外部状态驱动的区域,但慎用——可能破坏响应式一致性
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










