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