1)、为什么用Vue.nextTick()
首先,JS是单线程的,那么,它如何处理异步操作。
- 所有同步任务都在主线程上执行,形成一个执行栈。
- 主线程之外,会存在一个任务队列,只要异步任务有了结果,就在任务队列中放置一个事件(所以,也叫事件队列),进行排队(处于等待状态)。
- 当执行栈中的所有同步任务执行完后,就会读取任务队列(事件队列)中的任务(事件)。即:任务队列中的任务就结束了等待状态,进入执行栈。
- 主线程不断重复第三步。直到任务队列和执行栈里的代码执行完毕。
了解一个事件循环: https://blog.csdn.net/jiang7701037/article/details/95887439
其次,vue更新DOM的思路。使用的就是异步更新队列,所以,就使用了事件循环。目的是提高性能,避免无效的重复的DOM更新。即:vue中更新数据后,并不会立即更新DOM,而是把数据引起的DOM更新放入到异步更新队列里。等待下次事件循环(tick),并在两个tick之间进行UI渲染。这样程序员就不能在更改数据后,立即获取更新后的DOM,也不知道什么时候DOM能够更新。基于此,vue提供了nextTick函数。让程序员操作更新后DOM的代码放入到nextTick的回调函数里。由nextTick内部,在更新完DOM后,调用回调函数。
2)、什么是Vue.nextTick()
Vue.nextTick的代码思路示意
那么,vue是如何知道DOM更新了?
MutationObserver:这是HTML5新增的API。用于监视DOM变动的接口,它可以监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等
另外,考虑到,微任务比宏任务耗时少,浏览器的兼容性。所以,vue中延迟调用优先级如下: Promise > MutationObserver > setImmediate > setTimeout
3)、应用场景:
在Vue生命周期的created()钩子函数里,如果要进行DOM操作,一定要把DOM操作放在Vue.nextTick()的回调函数中。
在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作应该放在Vue.nextTick()的回调函数中。
<template>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="img in imgs"