← [ BACK_TO_NOTES ]

Vue 渲染与更新流程

从状态变更到 DOM 更新的主链路:依赖收集、触发、调度、虚拟 DOM patch。

#synthesis #growing #frame #vue3

[!info] Related notes

Vue 渲染与更新流程

这个概念为什么出现

只知道 ref 一改页面会变,却说不清:

  • 为什么多次修改只渲染一次
  • nextTick 为何存在
  • 组件更新边界在哪

需要一条从响应式触发到 DOM patch 的主链路。

[!abstract] 一句话理解 状态变更 → 触发依赖 → 调度组件更新任务 → 重新渲染 VNode → patch 到 DOM。

最小可观察示例

场景:一次点击内批量记录三次扫码

<script setup>
import { ref, nextTick } from 'vue'
const qty = ref(0)
const button = ref(null)

async function scanBurst() {
  qty.value++
  qty.value++
  qty.value++
  // 状态已是新值,当前这段同步代码中的 DOM 仍是本轮更新前的值。
  console.log('before tick', button.value?.textContent, qty.value)
  await nextTick()
  console.log('after tick', button.value?.textContent, qty.value)
}
</script>

<template>
  <button ref="button" type="button" @click="scanBurst">{{ qty }}</button>
</template>

在已挂载的 Vue 3 单文件组件中第一次点击,预期日志为 before tick 0 3、after tick 3 3。三次赋值发生在同一段同步代码内;三次独立用户点击不保证合并为一次更新。

核心链路

flowchart LR
  A[改 ref/reactive] --> B[trigger 依赖]
  B --> C[scheduler 排队]
  C --> D[组件 render 出 VNode]
  D --> E[diff/patch DOM]
  1. 依赖收集:渲染时 track 用到的响应式数据
  2. 触发:响应式值发生有效变更时通知依赖;相同值赋回不一定触发更新,未被当前渲染使用的状态也不必引起该组件更新
  3. 调度:组件更新任务默认排队并去重;状态值自身已同步改变,不是等 nextTick 才变
  4. 渲染:生成新 VNode 树
  5. 提交:diff/patch 更新需要变化的 DOM,结合编译期优化;不是承诺全局最少的 DOM 操作数

边界

  • 详情以当前 Vue3 实现为准,名称是教学模型
  • watch/watchEffect 有自己的调度选项;例如 flush: sync 会同步执行,不能把组件批处理规则套到所有 effect
  • nextTick 等待当前待处理的 Vue DOM 更新,不保证浏览器已经绘制,也不等待网络请求、图片、字体或动画完成
  • 本文描述 Vue 3 的常规 Virtual DOM 组件渲染;不同版本及渲染模式的内部实现需分别核对
  • 直接操作 DOM 可能被后续 patch 覆盖

工程实践

  • 需要 DOM 测量时用 nextTick
  • 大列表优化先看更新粒度与 key
  • 避免在渲染路径制造新的不必要响应式对象

验证记录:Vue 3.5.43 + jsdom 30.1.2 下编译并挂载原单文件组件,首次点击日志为 before tick 0 3、after tick 3 3;另验证同段三次修改触发同步 watcher 3 次、默认 watcher 1 次。未将 DOM 更新视为屏幕绘制验证。

本节总结

Vue 更新是“响应式通知 + 调度合并 + VDOM 提交”的流水线,不是每个赋值立即同步改 DOM。

自测题

  1. 为什么多次 qty.value++ 通常不会同步渲染三次?
  2. nextTick 解决什么?
参考答案
  1. 更新调度会合并到同一轮渲染。
  2. 在相关状态修改后等待 Vue 的 DOM 更新完成,再读取 DOM;它不是浏览器绘制完成或全部异步任务完成的信号。

参考

创建于 2026/3/19 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本