nextTick
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。
使用方法
代码语言:javascript复制this.$nextTick(function(){// 更新了dom})
vue2.1.0后返回了Promise对象,所以可以使用.then()或者结合async await语法糖使用
复制代码
使用场景
在弹出对话框的同时通过ref获取内嵌表格的实例。需等待此次DOM更新完毕,表格组件被挂载到父组件上才能正确获取。这时候就需要结合this.$nextTick使用。
代码语言:javascript复制async onOpenDialog() {
this.model.visible = true
// undefined
console.log(this.$refs.form)
setTimeout(function() {
// window
console.log(this)
}, 100)
this.$nextTick(function() {
// parent vm 有疑惑吗?
console.log(this)
// form vm
console.log(this.$refs.form)
})
await this.$nextTick()
// form vm
console.log(this.$refs.form)
this.$nextTick().then((vm)=>{
// parent vm
console.log(vm)
// form vm
console.log(this.$refs.form)
})
}
复制代码
源码解析
代码语言:javascript复制function nextTick (cb, ctx) {
var _resolve;
// 放入回调函数,等待DOM重新渲染完毕后执行
callbacks.push(function () {
if (cb) {
try {
// 修改执行上下文,指向当前页面实例
// 所以在我们没有使用箭头函数的前提下,this指向仍然正确
cb.call(ctx);
} catch (e) {
handleError(e, ctx, 'nextTick');
}
} else if (_resolve) {
_resolve(ctx);
}
});
if (!pending) {
pending = true;
timerFunc();
}
// $flow-disable-line
if (!cb && typeof Promise !== 'undefined') {
return new Promise(function (resolve) {
_resolve = resolve;
})
}
}
// 原型链上,挂载此方法
Vue.prototype.$nextTick = function (fn) {
//参数1:回调函数,参数二:页面实例执行上下文
return nextTick(fn, this)
};
复制代码