1. Vue 3.5 useId SSR 友好 ID 在水合不一致的工程价值
Vue 3.5 新增的 useId() 组合式函数如何生成 SSR 友好的 ID?它在解决水合(hydration)不一致问题上有怎样的工程价值?
- useId() 基于组件树位置生成确定性 ID 的实现思路
- SSR 下服务端与客户端 ID 不一致导致 Hydration Mismatch 的成因
- 与 useTemplateRef、表单 label/for 关联、无障碍 aria 属性等场景的配合
useId() 是 Vue 3.5 提供的组合式函数,用于生成在服务端渲染与客户端水合时保持一致的唯一 ID。它基于组件在组件树中的位置(父组件递增计数)推导出如 v-0、v-1 形式的字符串:同一个组件实例内多次调用返回稳定值,不同实例间则通过树位置区分,从而保证"同一次渲染在服务端与客户端结果相同"。这从根本上避免了传统 Math.random()、Date.now() 等方案因服务端与客户端分别执行而产生不同 ID 的问题,消除了因 id 属性不匹配触发的 Hydration Mismatch 警告。
水合不一致的本质是渲染过程存在非确定性。useId() 将 ID 生成从"运行时随机"改为"基于组件树位置的确定性推导",因此服务端与客户端输出完全一致。它特别适合表单 label 的 for 关联、aria-controls/aria-labelledby 等无障碍关联、以及需要稳定 ID 的自定义元素场景,既提升水合稳定性又改善可访问性,是 SSR 应用中生成 ID 的标准做法。
<script setup>
import { useId } from 'vue'
const inputId = useId() // 服务端与客户端渲染结果一致,如 v-0
</script>
<template>
<div>
<label :for="inputId">用户名</label>
<input :id="inputId" type="text" />
</div>
</template>