Vue2中有个nextTick
函数,这个函数是在更改数据后当你想立即使用js操作新的视图的时候需要使用它,nextTick
是在下次 DOM 更新循环结束之后执行延迟回调。源码在此, 可以去看看。以下是一个简图:
可以看到,vue会维护一个callbacks栈,可以通过Promise,MutatuinObserver等执行并清空,vue的策略是通过Promise这种可以函数,将callbacks栈清空的任务放在微任务,也会提供降级,当不支持微任务的时候会通过setTimeout
创建宏任务。
当我们调用nextTick
时,会往callbacks栈中压一个回调,同时会调用一下timerFunc执行一下推入微任务的函数,此时在下一次事件循环时会执行微任务中的回调了。当然,如果重复执行timerFunc并不会重复的创建微任务,而是将回调函数压入callbacks栈,一次全部执行完毕。
至于为啥可以在修改响应式数据之后在下一次微队列能获取到更新后的dom元素,那么就得知道修改vue中的data数据后,vue会在什么时候更新dom? 源码在此。修改数据后,会触发对象的set方法,会通知watcher,从而触发watcher的update方法,update方法内会将watcher添加进watcher队列,执行nexttick,把清空wacher队列的方法加入到微任务,等待同步事件执行完成后,浏览器就会执行微任务,从而更新dom。
简要总结
当响应式数据更新时,立马会有一个用于更新dom的微队列任务压入,此时执行nextTick
压入的微队列任务自然是在更新dom的操作之后了。