Skip to page content
Quasar CLI with Vite - @quasar/app-vite

客户端 Hydration(水化)

Hydration(水化)是指客户端的一个过程:Vue 接管服务器发送的静态 HTML,将其转变为能够响应客户端数据变化的动态 DOM。

既然服务器已经渲染好了 HTML 标签,我们当然不希望把它们丢掉再重新创建所有 DOM 元素。我们要做的是"hydrate"(水化)这些静态标签,让它们变得可交互。

WARNING

Vue 在开发模式下会报告 hydration 不匹配,并尝试通过调整 DOM 来恢复。这种恢复有性能开销并可能导致错误行为,因此在部署前应将每个意外的不匹配视为 bug 处理。

Hydration 注意事项

服务端和客户端必须产生相同的初始标记。不匹配的常见原因包括:

  • 无效的 HTML,浏览器在 Vue hydration 之前修复了它
  • 仅在浏览器端可用的值,如视口尺寸
  • 时间、随机值或因环境差异导致的格式化差异
  • 在服务端渲染和客户端 hydration 之间发生变化的数据
  • 在 setup 期间访问 DOM 的仅客户端第三方库

例如,浏览器会向以下无效的表格结构中插入 <tbody>

<table>
  <tr>
    <td>hi</td>
  </tr>
</table>

显式编写该元素以使浏览器 DOM 与 Vue 的预期结构匹配:

<table>
  <tbody>
    <tr><td>hi</td></tr>
  </tbody>
</table>

当内容只能在浏览器中渲染时,使用 QNoSsr。对于不可避免的、有意为之的差异,Vue 还支持 data-allow-mismatch 属性;请尽可能缩小其作用范围,而不是用它来掩盖其他无关的 hydration 问题。

处理 Hydration 错误

当 Vue 报告不匹配时:

  1. 使用 quasar dev -m ssr 复现问题,以启用开发模式诊断信息。
  2. 阅读控制台消息,在 Vue Devtools 或浏览器 DevTools 中检查引用的组件和 DOM 节点。
  3. 在 Network 面板中对比服务端响应与 hydration 之前的 DOM。
  4. 检查组件及其依赖项是否使用了浏览器全局对象、不确定性值、无效 HTML 或请求特定的状态。
  5. 直接刷新路由,同时也从其他页面导航到该路由。仅在直接加载时出现的不匹配通常指向不同的服务端和客户端初始化。
  6. 修正不同的初始状态,或将仅客户端内容延迟到挂载后再渲染。

不要依赖生产模式来掩盖不匹配问题;生产构建提供的诊断信息更少。