📖 概述
useId()
?是 Vue 3 中的一個組合式 API 函數,用于生成唯一的標識符。它確保在服務端渲染(SSR)和客戶端渲染之間生成一致的 ID,避免水合不匹配的問題。
🎯 基本概念
什么是 useId?
useId()
?返回一個唯一的字符串標識符,該標識符在組件的整個生命周期內保持不變,并且在服務端和客戶端之間保持一致。
使用場景
- 🏷? 為表單元素生成唯一 ID
- 🔗 關聯 label 和 input 元素
- 🎯 為 ARIA 屬性提供唯一標識
- 🔍 為測試提供穩定的選擇器
🔧 函數簽名
function useId(): string;
💻 代碼示例
🚀 基礎用法
<script setup lang="ts">
import { useId } from "vue";// 生成唯一標識符
const id = useId();console.log(id); // 例如: "v-1a2b3c4d"
</script><template><div><label :for="id">用戶名</label><input :id="id" type="text" /></div>
</template>
🏷? 表單元素關聯
<script setup lang="ts">
import { useId } from "vue";const inputId = useId();
const checkboxId = useId();
</script><template><div class="form-group"><label :for="inputId">郵箱地址</label><input :id="inputId" type="email" placeholder="請輸入郵箱" /><div class="checkbox-group"><input :id="checkboxId" type="checkbox" /><label :for="checkboxId">訂閱新聞</label></div></div>
</template>
🎯 ARIA 屬性支持
<script setup lang="ts">
import { useId } from "vue";const dialogId = useId();
const descriptionId = useId();
</script><template><divrole="dialog":aria-labelledby="dialogId":aria-describedby="descriptionId"><h2 :id="dialogId">確認刪除</h2><p :id="descriptionId">此操作不可撤銷,請確認是否繼續。</p><button @click="confirm">確認</button><button @click="cancel">取消</button></div>
</template>
🔍 多個組件實例
<script setup lang="ts">
import { useId } from "vue";// 每個組件實例都會生成不同的 ID
const containerId = useId();
const listId = useId();
</script><template><div :id="containerId" class="dropdown"><button :aria-expanded="isOpen" :aria-controls="listId">選擇選項</button><ul :id="listId" role="listbox" v-show="isOpen"><li role="option" v-for="item in items" :key="item.id">{{ item.name }}</li></ul></div>
</template>
?? 與其他 ID 生成方式的對比
? 不推薦的方式
<script setup lang="ts">
// 使用 Math.random() - 服務端和客戶端不一致
const randomId = Math.random().toString(36).substr(2, 9);// 使用 Date.now() - 可能導致重復
const timestampId = Date.now().toString();
</script>
? 推薦使用 useId
<script setup lang="ts">
import { useId } from "vue";// 使用 useId - 服務端和客戶端一致
const stableId = useId();
</script>
?? 注意事項
🔢 ID 唯一性
useId()
?生成的 ID 在同一個組件實例中是唯一的,但在不同的組件實例中會不同:
<script setup lang="ts">
import { useId } from "vue";const id1 = useId(); // 第一個組件實例的 ID
const id2 = useId(); // 第二個組件實例的 ID// id1 !== id2
</script>
📝 SSR 兼容性
useId()
?確保在服務端渲染和客戶端水合時生成相同的 ID:
<script setup lang="ts">
import { useId } from "vue";const id = useId();// 在服務端和客戶端都會生成相同的 ID
// 避免了水合不匹配的問題
</script>
🛡? 使用限制
useId()
?只能在組件的 setup 函數或?<script setup>
?中使用:
<script setup lang="ts">
import { useId } from "vue";// ? 正確:在 setup 中使用
const id = useId();// ? 錯誤:不能在事件處理函數中使用
const handleClick = () => {const newId = useId(); // 這會導致錯誤
};
</script>
🎯 最佳實踐
1?? 為表單元素生成 ID
<script setup lang="ts">
import { useId } from "vue";const inputId = useId();
const textareaId = useId();
const selectId = useId();
</script><template><form><div class="form-field"><label :for="inputId">姓名</label><input :id="inputId" type="text" /></div><div class="form-field"><label :for="textareaId">描述</label><textarea :id="textareaId"></textarea></div><div class="form-field"><label :for="selectId">城市</label><select :id="selectId"><option value="beijing">北京</option><option value="shanghai">上海</option></select></div></form>
</template>
2?? 組合多個 useId
<script setup lang="ts">
import { useId } from "vue";const baseId = useId();
const inputId = `${baseId}-input`;
const labelId = `${baseId}-label`;
const errorId = `${baseId}-error`;
</script><template><div class="form-control"><label :id="labelId" :for="inputId">密碼</label><input:id="inputId":aria-labelledby="labelId":aria-describedby="errorId"type="password"/><span :id="errorId" class="error-message"> 密碼長度至少6位 </span></div>
</template>
3?? 在可復用組件中使用
<script setup lang="ts">
import { useId } from "vue";interface Props {label?: string;error?: string;
}const props = defineProps<Props>();
const inputId = useId();
const errorId = useId();
</script><template><div class="input-wrapper"><label v-if="label" :for="inputId">{{ label }}</label><input :id="inputId" :aria-describedby="errorId" v-bind="$attrs" /><span v-if="error" :id="errorId" class="error">{{ error }}</span></div>
</template>
? 常見問題
Q: useId 生成的 ID 格式是什么?
A:?
useId()
?生成的 ID 格式類似?"v-1a2b3c4d"
,以 “v-” 開頭,后跟隨機字符串。
Q: 可以在條件渲染中使用 useId 嗎?
A: 可以,但要注意 ID 在組件的整個生命周期內保持不變,即使元素被條件渲染。
Q: useId 和 ref 有什么區別?
A:?
useId()
?用于生成唯一標識符,ref()
?用于創建響應式引用。它們的用途完全不同。
📝 總結
useId()
?是 Vue 3 中處理唯一標識符的標準方式,特別適用于表單元素、ARIA 屬性和 SSR 場景。它確保了服務端和客戶端之間的一致性,避免了水合不匹配的問題。在需要唯一 ID 的場景中,始終優先使用?useId()
?而不是其他隨機生成方式。
?Vue 3 useId 完全指南:生成唯一標識符的最佳實踐 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿技術分享