vue侦听器的flush选项控制回调执行时机:'pre'在更新前清理任务,'post'在dom更新后操作真实dom,'sync'同步执行需慎用;watcheffect支持相同flush且更简洁。

Vue 的侦听器(watch 和 watchEffect)默认在响应式数据变化后、组件更新前执行回调,但很多时候你需要更精确地控制它——比如操作刚渲染出来的 DOM,或清理上一轮未完成的任务。这时 flush 就是关键开关。
flush: 'pre' —— 更新前预处理(默认行为)
不写 flush 时,Vue 就按 'pre' 执行。此时响应式数据已更新,但视图还没重绘,DOM 还是旧的。
- 适合做清理工作:取消 pending 请求、清除定时器、中断动画
- 能读到最新的
ref.value或 reactive 数据,但拿不到新 DOM 元素 - 避免在回调里改监听源,否则可能触发重复执行或状态错乱
flush: 'post' —— 更新后操作真实 DOM
这是操作 DOM 的标准时机。回调会在 Vue 完成模板渲染、真实 DOM 更新完毕后,在下一个微任务中执行。
- 适用于
focus()、scrollIntoView()、getBoundingClientRect()等依赖布局的操作 - 和
nextTick()效果接近,但语义更明确,且与 watch 生命周期天然对齐 - 必须配合
ref正确绑定元素,确保ref.value在回调中非空
flush: 'sync' —— 同步立即执行(慎用)
数据一变,回调立刻同步运行,跳过 Vue 的批量更新调度机制。
- 会破坏响应式系统的优化逻辑,可能导致重复执行、渲染撕裂甚至无限循环
- 仅建议用于纯副作用场景:打日志、性能埋点、调试输出等不修改响应式状态的操作
- 日常业务中基本不需要,遇到性能异常时优先排查是否误用了
sync
watchEffect 的快捷替代方案
如果你只关心“数据变了就执行某事”,且不需要旧值,watchEffect 更简洁。它也支持 flush,还自带初始化执行:
-
watchEffect(() => { ... }, { flush: 'post' })等价于带flush: 'post'的watch -
watchPostEffect(() => { ... })是watchEffect的语法糖,固定使用flush: 'post' - 无需手动指定监听源,依赖自动追踪,代码更少、出错率更低
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










