Vuetify v-text-field 使用watch 改變資料時未同步更新問題

Willy
Sep 20, 2022

--

需求是有一個v-text-field要設定上限不可以超過2000,如下圖:

畫面
html

所以我們會需要一個watch隨時監控這個值:

watch

當輸入3000時會馬上跳回2000,但在後面輸入0之後,發現它還是可以繼續輸入,並不會跳回2000:

這時我們打開vue devtool 發現它的值一直是在2000沒有錯誤:

v-model綁定的變數

這才發現是畫面沒有更新,但資料是正確的;

搜尋過後發現應該可以用nextTick解決此問題,因此我們在watch的地方加上nextTick,測試過後發現一切都正常了。

composition api import 方式
watch 加上 nextTick
可以成功限制在2000了

那nextTick是什麼神奇魔法呢?簡單來說就是:

等待畫面更新後才執行程式

Vue 2 的官方文件有提到:

當你在 Vue 中更改響應式狀態時,最終的 DOM 更新並不是同步生效的,而是由 Vue 将它們缓存在一個列隊中,直到下一個“tick”才一起執行。這樣是為了確保每個組件無論發生多少狀態改變,都僅執行一次更新。

nextTick() 可以在狀態改變後立即使用,以等待 DOM 更新完成。你可以傳遞一个回調(call back)函數作為參數,或者 await 返回的 Promise。

所以point 超過2000後,我們會回寫v-model所綁定的資料(state.point),造成watch再次被觸發,而當我們修改時,Vue 不會馬上更新畫面,而是採用非同步來更新畫面。因此,如果我們需要操作最新的 DOM,就需要等 Vue 更新好畫面後才執行,否則只會操作舊的 DOM。

在下方參考來源中會有其他範例,可以更清楚了解原理:

參考來源:不只懂 Vue 語法:為什麼需要使用 $nextTick ?

--

--

Willy
Willy

Written by Willy

前端修練筆記本,記錄一些踩雷及學習過程,希望能順便幫助一些,在學習或開發路上卡關的人們。

No responses yet