官方定义:
在下次Dom更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。
场景:
在给子组件传参上;我们给子组件传参数后,在子组件中调用函数查看参数。
<div id="app">
<div class="msg">
<form-report ref="child" :name="childName"></form-report>
</div>
</div>
Vue.component('form-report', {
props: ['name'],
methods: {
showName(){
console.log('子组件name:'+this.name)
}
},
template: '<div>{{name}}</div>'
})
new Vue({
el: '#app',
data: function(){
return {
childName: '',
}
},
mounted(){
this.childName = '我是子组件名字'
this.$refs.child.showName()
}
})
虽然页面上展示了子组件的name,但是打印出来却是空值:
当我们想要在给data中数据赋值后立马去查看数据,却发现无法获取到。
获取你有没有想过,在页面中显示数据msg=0,然后对msg for循环100次++,页面上的数据是怎么变化的?(直接显示99)
主要原理:
赋值在vue中会被看做异步操作,而查看数据则是同步数据。根据事件循环机制所以每次获取到的都是旧数据。来看看vue的官方解释吧:
可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。
那么为了在数据更新操作之后操作dom,我们可以在数据变化之后立即使用vue.nexttick(callback);这样回调函数会在DOM更新完成后被调用,就可以拿到最新的DOM元素了。
nexttick(callback)源码分析流程:
1.把回调函数放入callbacks等待执行;
2.将执行函数放到微任务或者宏任务中;
3.事件循环到了微任务或者宏任务,执行函数依次执行callbacks中的回调。