flush 参数决定 watch 回调执行时机:pre(默认)在 dom 更新前,适合数据联动;post 在 dom 更新后,适合操作新 dom;sync 同步执行,易引发问题,应慎用。

flush 参数用来决定 watch 回调函数在响应式数据变化后、DOM 更新过程中的**具体执行时机**。它不是可有可无的配置,而是直接影响你能否拿到更新后的 DOM、是否引发重复更新、甚至影响性能的关键开关。
flush: 'pre'(默认值)——在 DOM 更新前执行
这是 Vue3 中 watch 的隐式默认行为(等价于显式写 flush: 'pre')。数据一变,watch 回调立刻执行,但此时 Vue 还没开始更新组件、也没刷新 DOM。
- 适合在数据变化后「提前干预」其他状态,比如联动修改另一个 ref,让它们一起批量更新,减少渲染次数
- 回调里访问
document.getElementById或ref.value拿到的仍是旧 DOM 节点或旧值 - 常见于表单联动、条件计算、避免冗余触发等逻辑
flush: 'post'——在 DOM 更新完成后执行
回调会延迟到整个组件更新完毕、真实 DOM 已刷新之后才运行,效果接近手动调用 nextTick,但更精准、更语义化。
- 当你需要操作更新后的 DOM(比如聚焦输入框、滚动到某位置、测量元素尺寸)时,必须选它
- 子组件完成挂载或更新后,它的 ref 才真正可用,
post是安全读取的时机 - 注意:如果回调里又改了响应式数据,会触发新一轮更新,需防止循环依赖
flush: 'sync'——同步立即执行
数据一变化,回调立刻同步运行,不等待任何队列或更新周期。它绕过了 Vue 的异步更新队列机制。
- 极少需要,仅适用于极特殊场景,比如调试、与非 Vue 系统做强实时同步
- 容易导致 DOM 访问错乱(可能拿到未更新的 DOM)、性能下降、甚至无限循环(例如回调里又改了被监听的值)
- 生产环境慎用,除非你完全清楚副作用链和响应式触发顺序
怎么选?看你的目标
想改数据、做计算、避免多次渲染 → 用默认 pre;
想拿新 DOM、操作真实元素、等子组件就绪 → 用 post;
除非有明确且不可替代的理由,否则别碰 sync。











