Vue 推出了新特性 useId,能提高多少開發體驗?
在 Vue3.5 這個版本中,新增了 useId 這一個 API,它的功能是用來生成一個 唯一的ID,為什么說它生成的 ID 是唯一的呢?我們可以來看看 useID 的源碼,你就知道了。
其實原理很簡單,就是調用 getCurrentInstance 這個,這個 API 會返回當前 Vue 實例的信息對象,而這個信息對象身上有一個 ids 的數組,而 useId 就是根據這個數組去生成唯一 ID 的。
圖片
- appContext.config.idPrefix: 這是可全局配置的 ID 前綴,如果你不配置,那就默認是 v。
- ids[0] + ids[1]++: 由唯一的 ids[0] 和遞增的 ids[1] 來實現同實例內與不同實例時間的唯一性。
想要設置 appContext.config.idPrefix 可以在 main.ts 中去設置。
圖片
接下來講一下 useId 都有哪些比較實用且常用的場景吧!
表單對應標識
表單中,我們會使用 label 來做表單項的展示文本,我們想要點擊這個展示文本,能自動聚焦到表單項上,那么我們可以同時給 label、表單項標簽 設置上一個一樣的 ID。
圖片
圖片
v-for 唯一 key
大家都知道,在 Vue 中使用 v-for 去循環遍歷一個列表的時候,需要給每一個遍歷項加上一個唯一 key ,確保 DOM 更新的時候能得到一定的性能提升,我們可以使用 useID 來生成一個唯一 key。
圖片
圖片
服務端渲染保持唯一性
使用 服務端渲染(SSR) 的應用里,頁面的 HTML 是由服務器生成的,隨后被傳送到客戶端的瀏覽器。當瀏覽器接收到這些 HTML 內容后,會將其轉變為一個可交互的頁面。然而,倘若服務器端與客戶端生成的 HTML 中具有相同的 ID,在客戶端進行 激活(hydrate) 操作時,就有可能出現問題。因為客戶端可能會試圖對一個已經被服務器端渲染好的 DOM元 素進行操作,這樣就會引發潛在的沖突或者錯誤。
可以通過一個小例子來說明這個問題。
服務端代碼
圖片
客戶端代碼
圖片
在這個案例中,無論是服務端還是客戶端,我們都使用了 createSSRApp(App) 來創建應用實例。如果我們在 App.vue 中使用了 useId 來生成 ID,那么這些 ID 將在服務端渲染時生成一次,并在客戶端激活時再次使用相同的 ID。
App.vue
圖片
在 App.vue 組件里,我們借助 useId為 <input> 元素創建了一個獨一無二的 ID。此 ID 在服務端渲染階段生成,并被納入發送至客戶端的HTML之中。當客戶端接收到該HTML并展開激活流程時,鑒于useId所生成的ID在服務端和客戶端保持一致,客戶端便能準確地把 <label> 元素與 <input> 元素相關聯,從而避免出現 ID 沖突的情況。
倘若不使用 useId,而是采用 Math.random() 或者 Date.now() 來生成 ID,那么服務端和客戶端有可能生成不一樣的ID。這就會致使客戶端在激活時無法正確地將 <label> 與 <input> 關聯起來,因為二者的 ID 存在差異。這種情況或許會致使表單元素出現行為異常,比如點擊 <label> 時,<input> 卻不能獲取焦點。
組件庫中 ID 的生成
在運用 Element Plus 等組件庫開展 SSR 開發的過程中,為防止出現 hydration 錯誤,務必要保證服務器端和客戶端所生成的 ID 是一致的。向 Vue 中注入 ID_injection_key 這一操作,能夠確保 Element Plus 所生成的 ID 在 SSR 里具備唯一性。
圖片