vue响应式系统依赖触发严格遵循“数据修改→依赖通知→更新执行”线性链条,通过异步批量更新机制统一调度,确保一次同步任务内多次赋值仅触发一次dom重渲染。

Vue 响应式系统中,依赖的触发顺序不是随机的,而是严格遵循“数据修改 → 依赖通知 → 更新执行”的线性链条,并受调度机制影响。关键不在于谁先谁后,而在于**谁被通知、何时通知、按什么规则执行**。
依赖触发由 set/Proxy.set 主动发起
当响应式数据被赋值(如 this.count = 5 或 state.obj.prop = 'new'),对应属性的 setter(Vue 2)或 set trap(Vue 3)立即被调用。此时系统会:
- 更新原始值
- 查找到该属性对应的依赖集合(即
Dep或WeakMap → Map → Set结构) - 遍历该集合中的所有活跃 Watcher(或 effect),将它们加入待更新队列
通知不等于立即执行:异步批量更新是默认行为
Vue 不会在每次 set 后立刻刷新视图,而是把所有待更新的 Watcher 暂存,等本轮同步任务结束后统一处理:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 所有同步代码执行完(包括多次赋值、嵌套修改)
- 进入微任务阶段(Vue 2 用
nextTick的 Promise,Vue 3 用queueJob+ Promise.then) - 按创建顺序(通常是组件挂载顺序)依次执行 Watcher 的
update方法
这意味着:this.a = 1; this.b = 2; 触发的两个依赖,最终只引发一次 DOM 重渲染,且内部更新顺序可预测。
计算属性与侦听器有优先级干预能力
虽然普通渲染 Watcher 按队列顺序执行,但以下两类依赖可改变实际触发节奏:
- computed:拥有缓存和懒求值特性。它的依赖只在被访问时才收集,更新也只在其依赖变化且自身被读取时才重新求值
-
watch with flush: 'sync' / 'pre':可强制提前执行。例如
flush: 'pre'会让侦听器在组件更新前运行,常用于 DOM 尺寸读取;flush: 'sync'则完全同步触发,跳过队列
嵌套响应式对象的触发是深度递归的
修改一个深层属性(如 state.user.profile.name = 'Alice')会逐层触发:
- 先触发
profile属性的 set(若 profile 是 reactive) - 再触发
name属性的 set - 每一层都会查找并通知各自绑定的依赖
- 但最终仍汇总到同一更新队列中,不会重复刷新
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









