一、nextTick是什么?
在下次DOM更新循环结束之后,执行延迟回调
Vue在更新DOM时是异步执行的,当数据发生变化,vue不会立刻去更新don,而是去开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新。
为什么要有nextTick?
如果没有nextTick更新机制,那么每次数据变化都会触发视图更新,(比如频繁更新10万次),有了nextTick机制,只需要更新一次,所以nextTick本质是一种优化策略。
二、使用场景
想要在数据修改后(想要在什么时候)立刻得到更新后的DOM,就可以使用Vue.nextTick()
第一个参数:回调函数(可以获取到最近DOM结构)
第二个参数:执行上下文
vm.message = '修改后的值'
//此时DOM还没更新
console.log(vm.$el.textContent) //原来的值
Vue.nextTick(function() {
//DOM更新了
console.log(vm.$el.textContent) //修改后的值
})
组件内通过this.$nextTick(),并且回调函数中的this自动绑定到当前的Vue实例上
this.message = '修改后的值'
console.log(this.$el.textContent) // => '原始的值'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '修改后的值'
})
$nextTick()会返回一个Promise对象,可以用async/await代替
三、实现原理
总结:
1、把回调函数放到callbacks等待执行
2、将执行函数放到微任务或宏任务中
3、事件循环到了微任务或者宏任务,一次执行callbacks中的回调
如果支持 Promise 就用 Promise
如果不支持就用 MutationObserver MDN-MutationObserver
MutationObserver 它会在指定的DOM发生变化时被调用
如果不支持 MutationObserver 的话就用 setImmediate MDN-setImmediate
但是这个特性只有最新版IE和node支持,然后是最后一个条件 如果这些都不支持的话就用setTimeout
顺序就是:promise -> MutationPbserver -> setImmediate -> setTimeout
跟Event Loop有关(单进程、同步异步、微任务宏任务)