标准答案
- Hydration 是客户端接管服务端已生成 HTML 的过程,前提是客户端首次渲染结果要和服务端 HTML 对得上。
- 常见不一致原因包括 Date、Math.random、localStorage、window 尺寸、用户环境判断、异步数据返回差异和权限状态不同。
- 组件只在客户端可用时,要使用客户端专用渲染边界,避免服务端输出和客户端首屏不一致。
- 定位时先看控制台 hydration warning,再缩小到具体组件,比较服务端 HTML、客户端初始 state 和首次渲染条件。
- 修复思路是让首屏输入稳定:服务端预取数据、避免首屏随机值、把浏览器 API 放到 mounted 后或客户端组件里。
题目解析
SSR 的难点不只是把页面在服务端渲染出来,而是保证客户端接管时第一帧语义一致。
Nuxt 项目里很多 hydration 问题来自 useAsyncData key 不稳定、服务端和客户端请求条件不同,或者组件内部直接读取浏览器环境。
Teleport、弹窗、主题、国际化和权限菜单都可能影响首屏结构,排查时要关注它们是否两端输出一致。
代码示例
下面的写法容易造成服务端和客户端首屏文本不同。
Vue
<template>
<p>{{ Math.random() }}</p>
</template>Vue
<script setup lang="ts">
const mounted = ref(false)
onMounted(() => {
mounted.value = true
})
</script>
<template>
<ClientOnly>
<UserOnlyWidget v-if="mounted" />
</ClientOnly>
</template>常见误区
- 把 hydration warning 当成可以忽略的开发环境噪音。
- 在 setup 首屏阶段直接读取 window、localStorage 或随机值。
- 服务端和客户端分别请求数据,但 key、参数或权限态不一致。