I am using Nuxt.js / Vuejs for mmy app, and I keep facing this error in different places:
The client-side rendered virtual DOM tree is not matching server-rendered content.
This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>.
Bailing hydration and performing full client-side render.
I would like to understand what is the best way to debug this error? Is their a way I can record/get the virtual DOM tree for client and server so I could compare and find where the error lies?
Mine is a large application and manually verifying is difficult.
答案 0 :(得分:28)
部分答案:使用Chrome DevTools,您可以本地化问题并确切了解导致问题的元素。执行以下操作(我使用Nuxt 5.6.0和Chrome 64.0.3282.186执行此操作)
msg
变量上来检查消息。 hydrate
函数上,调用patch
中执行行上方的4行。将打开hydrate
来源的超链接。 hydrate
函数中,从一开始就移动大约15行,并设置一个断点,false
返回assertNodeMatch
后返回false
。在那里设置断点并删除所有其他断点。 hydrate
函数中停止。切换到DevTools控制台并评估elm
,然后评估vnode
。这里elm似乎是一个服务器呈现的DOM元素,而vnode是一个虚拟DOM节点。 Elm以HTML格式打印,因此您可以找出错误发生的位置。答案 1 :(得分:11)
对我来说,发生此错误是因为cuz在AsyncData
中获取数组列表,并由<tr>
渲染了v-for
标签,我在v-for
块中放置了<client-only>
代码,并出现了问题解决了
答案 2 :(得分:4)
在实现vue-particles软件包时,我遇到了与nuxt 2.14.0版相同的问题。 解决方法是围绕标签no-ssr并解决了该问题。 例子:
<no-ssr>
<vue-particles>
</vue-particles>
</no-ssr>
答案 3 :(得分:3)
对于高于2.10的Nuxt版本,它不需要安装任何东西,只需使用默认的组件<client-only>
,如https://nuxtjs.org/api/components-client-only/所述。
答案 4 :(得分:2)
此错误真的很难调试。为了快速获取引起问题的元素,请编辑node_modules/vue/dist/vue.esm.js
并添加以下几行:
// Search for this line:
function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
var i;
var tag = vnode.tag;
var data = vnode.data;
var children = vnode.children;
inVPre = inVPre || (data && data.pre);
vnode.elm = elm;
// Add the following lines:
console.log('elm', elm)
console.log('vnode', vnode)
console.log('inVpre', inVPre)
// ...
您将在控制台中找到发生故障的节点。
答案 5 :(得分:2)
如果您使用 v-if
有条件地渲染组件,那么您有两种选择来解决该问题:
第一个是将元素包裹在 <no-ssr></no-ssr>
标签中。
第二种方法是用 v-if
替换 v-show
,here 是 Vue 文档的链接。
答案 6 :(得分:1)
结果,就我而言,我有HTML注释标签,这引起了这个愚蠢,令人讨厌的错误。花了我很长时间才弄清楚它,但万一它对某人有帮助。
答案 7 :(得分:1)
就我而言,我必须更改此设置:
<v-expansion-panel-header v-text="name" />
对此:
<v-expansion-panel-header>{{ name }}</v-expansion-panel-header>
答案 8 :(得分:1)
有很多方法可以解决这个问题,但其中大部分都不是真正的修复,只是临时用的创可贴。注意几点:
<client-only>
标签v-show
而不是 v-if
我强烈推荐阅读亚历山大·利希特 (Alexander Lichter) 撰写的这篇精彩的文章
<块引用>https://blog.lichter.io/posts/vue-hydration-error/
他会向您解释,您应该诊断为什么会发生这种情况并解决实际问题。
基本上每次与在服务器上生成的内容以及在客户端上完成补水后可用的内容不同时,都会导致此错误。
其中一些是:
<p>
中包含块元素是无效的)new Date()
)我强烈建议您阅读这篇文章,用 Alexandre 自己的话了解如何处理此类问题。如果您赶时间,您可以随时使用创可贴修复,但尝试实际修复问题以获得最佳性能并保持代码清洁。
答案 9 :(得分:0)
请参阅此处,以获取有关如何处理修改DOM的集成(例如Google Analytics(分析)或FB Pixel)的示例。基本上创建一个插件,并从SSR中排除。
答案 10 :(得分:0)
好吧,这听起来很愚蠢。我尝试了大约15分钟的各种解决方案,例如重新启动服务器和删除.nuxt目录,但是我懒得使用@ budden73的大脑力解决方案。最终对我有用的只是重新启动计算机,试一试。
答案 11 :(得分:0)
到目前为止,我发现还没有发现,当您使用jQuery之类的第三方程序包时(特别是),它们有时会在dom中注入html标签。因此,Vue / Nuxt松开了dom树的记录并开始抱怨。
我遇到了同样的问题,过了一会儿,我删除了所有jQuery,并用Vuejs替换了jQuery功能,这些错误都消失了。
答案 12 :(得分:0)
检查先前的警告:
在"nuxt": "^2.12.2"
中,您可以从先前的警告中轻松找出原因。
在我的情况下:
不正确
<nuxt-link to="/game42day">
<a>Game For Today</a>
</nuxt-link>
正确:
<nuxt-link to="/game42day">
Game For Today
</nuxt-link>
答案 13 :(得分:0)
那:
extend (config, ctx) {
config.resolve.symlinks = false
}
答案 14 :(得分:0)
检查是否在内联元素中使用了任何块级元素。
例如:里面,里面
如果您使用过 HTML 表格,请确保您使用了标签