外观
nextTick 什么时候用?
改完响应式数据后,DOM 还没更新。nextTick 的回调跑在 DOM 更新之后,用来读取更新后的节点。能不用就不用,多数逻辑应该依赖状态而不是依赖「下一帧 DOM 已经变了」。
原理
Vue 把一次事件循环里的多次数据修改收成一次渲染。渲染函数重新执行、虚拟 DOM 打补丁,都排在微任务里。nextTick 也是排一个微任务,并且保证在这次 DOM 补丁之后。
js
count.value += 1
await nextTick()
// 这里能读到新的文本宽度在 watch 里如果 flush: 'post',回调本身就在 DOM 更新之后,不必再套 nextTick。默认的 watch 在渲染前调用,这时读 DOM 还是旧的。
不要用 nextTick 去等待子组件的请求完成。请求完成是另一件事,用状态或 Promise。
追问
和 setTimeout(fn, 0) 比呢?
定时器是宏任务,会排到渲染甚至更多微任务之后,时机更晚,也可能闪一下。等的就是这次 DOM 更新时,用 nextTick。
连续改三次状态会回调几次?
三次修改如果发生在同一次刷新前,渲染只有一轮,nextTick 也只需要等这一轮。每个 nextTick 调用仍会各排一个回调。
易错点
- 数据一改就读
offsetHeight,读到的是旧布局。 - 在
nextTick里再改状态,触发第二轮渲染,形成不必要的来回。 - 把它当成通用的
sleep。