需求是有一個v-text-field要設定上限不可以超過2000,如下圖:
所以我們會需要一個watch隨時監控這個值:
當輸入3000時會馬上跳回2000,但在後面輸入0之後,發現它還是可以繼續輸入,並不會跳回2000:
這時我們打開vue devtool 發現它的值一直是在2000沒有錯誤:
這才發現是畫面沒有更新,但資料是正確的;
搜尋過後發現應該可以用nextTick解決此問題,因此我們在watch的地方加上nextTick,測試過後發現一切都正常了。
那nextTick是什麼神奇魔法呢?簡單來說就是:
等待畫面更新後才執行程式
Vue 2 的官方文件有提到:
當你在 Vue 中更改響應式狀態時,最終的 DOM 更新並不是同步生效的,而是由 Vue 将它們缓存在一個列隊中,直到下一個“tick”才一起執行。這樣是為了確保每個組件無論發生多少狀態改變,都僅執行一次更新。
nextTick()
可以在狀態改變後立即使用,以等待 DOM 更新完成。你可以傳遞一个回調(call back)函數作為參數,或者 await 返回的 Promise。
所以point 超過2000後,我們會回寫v-model所綁定的資料(state.point),造成watch再次被觸發,而當我們修改時,Vue 不會馬上更新畫面,而是採用非同步來更新畫面。因此,如果我們需要操作最新的 DOM,就需要等 Vue 更新好畫面後才執行,否則只會操作舊的 DOM。
在下方參考來源中會有其他範例,可以更清楚了解原理: