我对Vue.nextTick方法有些疑惑。在查阅了各种资料后,我总结了它的原理和用途。如果有任何错误,请告诉我。概述官方文档解释:用法:在下一个DOM更新周期结束后执行一个延迟回调。修改数据后立即使用此方法获取更新后的DOM。问题:什么是DOM更新周期?下一个更新周期是什么时候?是修改数据后用来加快数据更新进度的吗?应该在什么情况下使用?异步原理说明Vue对响应式的实现并不是在数据发生变化后立即改变DOM,而是按照一定的策略更新DOM。在Vue的文档中,声明Vue异步执行DOM更新。异步分析可以看看阮一峰老师的这篇文章。拦截的关键部分如下:具体来说,异步执行的运行机制如下。(1)所有的同步任务都在主线程上执行,形成一个执行上下文栈。(2)除了主线程之外,还有一个“任务队列”。只要异步任务有运行结果,就会在“任务队列”中放入一个事件。(3)一旦“执行栈”中的所有同步任务都执行完毕,系统就会去读取“任务队列”,看看里面有什么事件。那些对应的异步任务结束等待状态,进入执行栈,开始执行。(4)主线程不断重复上面的第三步。下图是主线程和任务队列的示意图。事件循环说明简单来说,Vue修改数据后,视图不会立即更新,而是在同一个事件循环中所有数据更改完成后,统一更新视图。知乎上的例子://Changedatavm.message='changed'//我想立即使用更新后的DOM。这行不通,因为在设置消息后DOM还没有更新(function(){console.log(vm.$el.textContent)//可以得到'changed'})图:事件周期:第一个tick(图例中的第一步,即'thisupdatecycle'):先修改数据,属于同步任务。同一个事件循环的所有同步任务都在主线程上执行,形成一个执行栈,DOM暂未涉及。Vue启动一个异步队列并缓冲在此事件循环期间发生的所有数据更改。如果同一个观察者被多次触发,它只会被推入队列一次。第二个tick(图中的第二个步骤,即'下一个更新周期'):同步任务执行完毕,开始异步watcher队列的任务更新DOM。Vue在内部尝试对异步队列使用原生的Promise.then和MessageChannel方法。如果执行环境不支持,它将使用setTimeout(fn,0)代替。第三个tick(图中第三步):此时文档中提到的下一个DOM更新周期结束后,通过Vue.nextTick获取变化的DOM。也可以通过setTimeout(fn,0)获取。事件循环简单总结:同步代码执行->找到异步队列,压入执行栈,执行Vue.nextTick[事件循环1]->找到异步队列,压入执行栈,执行Vue.nextTick[事件循环2]....简而言之,异步就是单次tick,不会和同步发生在同一个tick,这也是DOM不会立即变化的原因。关于事件循环,可以在这里查看更详细的内容:https://segmentfault.com/a/11...应用场景:视图更新后,需要基于新的视图进行操作。Created和mounted需要注意的是,在created和mounted阶段,如果需要对渲染视图进行操作,还应该使用nextTick方法。官方文档说明:注意mounted不保证所有子组件也一起挂载。如果你想等到整个视图渲染完成,你可以用vm.$nextTick替换mountmounted:})}其他应用场景其他应用场景如下:例1:点击按钮显示原本用v-show=false隐藏的输入框,并获得焦点。showsou(){this.showit=true//修改v-showdocument.getElementById("keywords").focus()//在第一个tick中,获取不到输入框,自然也就获取不到焦点}修改For:showsou(){this.showit=truethis.$nextTick(function(){//DOM更新document.getElementById("keywords").focus()})}示例2:点击获取元素宽度。
