1. 用nextTick()的原因:
JS運行機制(Event Loop)
JS執行是單線程的,它是基於事件循環的
- 所有同步任務都在主線程上執行,形成一個執行棧。
- 主線程之外,會存在一個任務隊列,只要異步任務有了結果,就在任務隊列中放置一個事件。
- 當執行棧中的所有同步任務執行完後,就會讀取任務隊列。那些對應的異步任務,會結束等待狀態,進入執行棧。
- 主線程不斷重複第三步。
- 這裏主線程的執行過程就是一個
tick
,而所有的異步結果都是通過任務隊列來調度。Event Loop
分爲宏任務和微任務,無論是執行宏任務還是微任務,完成後都會進入到一下tick
,並在兩個tick之間進行UI渲染。
Vue異步更新隊列(數據驅動視圖)
- 由於Vue DOM更新是
異步執行
的,即修改數據時,視圖不會立即更新,- 只要
監聽數據變化
,Vue 將開啓一個隊列,並緩衝在同一事件循環中
發生的所有數據變更,在緩衝時會去除重複數據,從而避免不必要的計算和DOM操作。- 然後,在下一個的事件循環“tick”中,Vue 刷新隊列並執行實際 (已去重的) 工作。
- 等同一數據循環中的所有數據變化完成之後,再統一進行視圖更新。
- 爲了確保得到更新後的DOM,所以設置了
Vue.nextTick()
方法。
2、什麼是nextTick()
在下次 DOM 更新循環結束之後執行延遲迴調。在修改數據之後立即使用這個方法,獲取更新後的 DOM。
Vue 在內部對異步隊列嘗試使用原生的
Promise.then
、MutationObserver
和setImmediate
,如果執行環境不支持,則會採用setTimeout(fn, 0)
代替。
3、nextTick()用法
全局中: Vue.nextTick
組件中: this.$nextTick
<span>{{ message }}</span>
data() {
return {
message: '未更新'
}
},
methods: {
updateMessage: function () {
this.message = '已更新'
console.log(this.$el.textContent) // => '未更新'
this.$nextTick(function () {
console.log(this.$el.textContent) // => '已更新'
})
}
}