客户端水化

水化是指客户端过程,在此过程中,Vue会接管服务器发送的静态HTML,并将其转换为可以对客户端数据更改做出反应的动态DOM。

由于服务器已经渲染了标记,因此我们显然不想扔掉标记并重新创建所有DOM元素。 取而代之的是,我们要“水化”静态标记并使之具有交互性。

WARNING

在开发模式下,Vue将断言客户端生成的虚拟DOM树与从服务器渲染的DOM结构匹配。 如果不匹配,它将阻止水化,丢弃现有的DOM并从头开始渲染。 在生产模式下,将禁用此断言以实现最佳性能。

水化注意事项

使用SSR +客户端连接时要注意的一件事是,浏览器可能会更改某些特殊的HTML结构。 例如,当您在Vue模板中编写此代码时:

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

浏览器将自动在<table>中注入<tbody>,但是,Vue生成的虚拟DOM不包含<tbody>,因此将导致不匹配。 为确保正确匹配,请确保在模板中编写有效的HTML。

处理水化错误

如果确实收到水化错误(如在控制台中看到的:“Vuejs Error - The client-side rendered virtual DOM tree is not matching server-rendered content”),则可以尝试执行以下步骤:

  1. 在Chrome中显示DevTools(F12)
  2. 加载引起“the client-side rendered virtual DOM tree…”警告的页面。
  3. 在DevTools控制台中滚动到警告。
  4. 在vue.runtime.esm.js中单击警告的源位置超链接。
  5. 在此处设置一个断点(在源代码浏览器中的行号上单击鼠标左键)。
  6. 再次显示相同的警告。通常通过重新加载页面。如果有很多警告,您可以通过将鼠标移到msg变量上来检查消息。
  7. 找到消息并在断点处停止后,请查看_call stack_。向下单击一帧调用“patch”以打开其源代码。将鼠标悬停在水化函数上方,会在补丁(patch)程序中执行上方的4行调用。水化源代码的超链接将打开。
  8. 在hydrate函数中,从起点开始移动约15行,并设置一个断点,在该断点处,在assertNodeMatch返回false之后返回false。在此处设置断点,然后删除所有其他断点。
  9. 再次发出相同的警告。现在,当遇到断点时,应该在hydrate函数中停止执行。切换到DevTools控制台,先评估elm,然后评估vnode。这里的elm似乎是一个服务器渲染的DOM元素,而vnode是一个虚拟的DOM节点。 Elm以HTML格式打印,因此您可以弄清楚错误发生的位置。