Vue渲染机制本质是响应式状态到DOM的精准高效映射与更新,分初始化映射、依赖追踪、按需更新三阶段;通过渲染函数生成VNode树,Proxy实现细粒度响应,Diff算法最小化DOM操作,统一渲染器驱动挂载与更新。

Vue 渲染机制的本质,是把响应式状态(data、ref、reactive 等)转化为用户可见的 DOM 视图,并在状态变化时精准、高效地更新对应部分。它不是一次性“重绘整个页面”,而是一套分阶段、有策略的演化过程:从初始化映射,到依赖追踪,再到按需更新。
模板或渲染函数定义状态与视图的映射关系
开发者通过 <template> 或显式编写 render() 函数,声明“某个状态值应如何呈现为 DOM 结构”。Vue 编译器(开发时)或运行时编译器会将模板转为渲染函数;该函数执行后返回一个虚拟节点(VNode)树——它是对真实 DOM 的轻量级 JavaScript 描述,不直接操作浏览器。
- 例如
{{ message }}在渲染函数中体现为h('p', this.message) - 每个 VNode 包含标签名、属性、子节点、key 等信息,但不含样式计算或布局细节
- 渲染函数本身是纯函数:相同输入(状态 + 上下文)总是产生相同 VNode 结构
响应式系统触发依赖收集与更新通知
当组件首次渲染时,渲染函数执行过程中会读取响应式数据(如 this.count 或 count.value),触发 Proxy 或 getter 拦截,Vue 自动将当前组件的更新函数(effect)记录为该数据的依赖。一旦数据被修改,系统立即通知所有关联的 effect 重新执行。
- Vue 3 使用
Proxy拦截对象任意属性,支持新增/删除属性的响应 - 基本类型用
ref()包装,通过.value访问,同样可被追踪 - 依赖是细粒度的:改
user.name不会触发依赖user.age的组件更新
虚拟 DOM Diff 与最小化 DOM 操作
组件更新时,会再次调用渲染函数生成新的 VNode 树。Vue 渲染器将新旧两棵 VNode 树进行深度对比(diff),聚焦于同层、同 key 的节点,跳过静态内容和未变动分支,最终生成一组“打补丁”指令(如 patchProp、move、remove)。
立即学习“前端免费学习笔记(深入)”;
- Diff 是双端比较:从头到尾、从尾到头同步推进,提升列表更新效率
- key 属性至关重要:没有 key 时 Vue 默认用“就地复用”策略,可能引发状态错位
- 真实 DOM 更新仅发生在必要位置,避免整块重绘或 layout thrashing
挂载与更新流程统一由渲染器驱动
无论是首次挂载(mount)还是后续更新(patch),都由同一套渲染器(Renderer)处理。它屏蔽了平台差异(如 DOM、Canvas、WebGL),只接收 VNode 输入,输出对应平台的真实节点操作。
- 初次挂载:VNode → createElement + appendChild → 插入真实 DOM
- 状态变更后:新 VNode → diff → patch → 增删改查真实节点
- 卸载时:清理事件监听、定时器、副作用,防止内存泄漏


















