javascript Vuejs 错误:客户端渲染的虚拟 DOM 树与服务器渲染的不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47862591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Vuejs Error: The client-side rendered virtual DOM tree is not matching server-rendered
提问by asanas
I am using Nuxt.js / Vuejs for mmy app, and I keep facing this error in different places:
我正在为 mmy 应用程序使用 Nuxt.js / Vuejs,但我在不同的地方一直面临这个错误:
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?
我想了解调试此错误的最佳方法是什么?他们是我可以记录/获取客户端和服务器的虚拟 DOM 树的一种方式,以便我可以比较并找出错误所在?
Mine is a large application and manually verifying is difficult.
我的是一个大型应用程序,手动验证很困难。
回答by budden73
Partial answer: with Chrome DevTools, you can localize the issue and see exactly what element caused the issue. Do the following (I did that with Nuxt 5.6.0 and Chrome 64.0.3282.186)
部分答案:使用 Chrome DevTools,您可以本地化问题并查看导致问题的确切因素。执行以下操作(我使用 Nuxt 5.6.0 和 Chrome 64.0.3282.186 执行此操作)
- Show DevTools in Chrome (F12)
- Load the page that causes "the client-side rendered virtual DOM tree..." warning.
- Scroll to the warning in DevTools console.
- Click at the source location hyperlink of the warning (in my case it was vue.runtime.esm.js:574).
- Set a breakpoint there (left-clicking at line number in the source code browser).
- Make the same warning to appear again. I'm not saying it is always possible, but in my case I simply reloaded the page. If there are many warnings, you can check the message by moving a mouse over
msgvariable. - When you found your message and stopped on a breakpoint, look at the call stack. Click one frame down to call to "patch" to open its source. Hover mouse over
hydratefunction call 4 lines above the execution line inpatch. Hyperlink to the source ofhydratewould open. - In the
hydratefunction, move about 15 lines from the start and set a breakpoint wherefalseis returned afterassertNodeMatchreturnedfalse. Set the breakpoint there and remove all other breakpoints. - Make the same warning to happen again. Now, when breakpoint is hit, execution should stop in the
hydratefunction. Switch to DevTools console and evaluateelmand thenvnode. Here elm seem to be a server-rendered DOM element while vnode is a virtual DOM node. Elm is printed as HTML so you can figure out where the error happened.
- 在 Chrome 中显示 DevTools (F12)
- 加载导致“客户端呈现的虚拟 DOM 树...”警告的页面。
- 滚动到 DevTools 控制台中的警告。
- 单击警告的源位置超链接(在我的例子中是 vue.runtime.esm.js:574)。
- 在那里设置断点(在源代码浏览器中左键单击行号)。
- 再次出现相同的警告。我并不是说这总是可能的,但就我而言,我只是重新加载了页面。如果有很多警告,您可以通过将鼠标移到
msg变量上来检查消息。 - 当您找到消息并在断点处停止时,请查看调用堆栈。单击向下一帧以调用“补丁”以打开其源代码。将鼠标悬停
hydrate在执行行上方 4 行的函数调用上patch。源的超链接hydrate将打开。 - 在
hydrate函数中,从开始处移动大约 15 行,并在false返回后assertNodeMatch返回的位置设置断点false。在那里设置断点并删除所有其他断点。 - 再次发出相同的警告。现在,当断点被击中时,执行应该在
hydrate函数中停止。切换到 DevTools 控制台并评估elm,然后vnode. 这里 elm 似乎是一个服务器渲染的 DOM 元素,而 vnode 是一个虚拟 DOM 节点。Elm 打印为 HTML,因此您可以找出错误发生的位置。
回答by Mohsen
For me this error happened cuz get Array list in AsyncDataand rendered <tr>tags by v-for, i put v-forcodes in <client-only>blocks and problem solved
对我来说,这个错误发生了,因为获取数组列表AsyncData并渲染<tr>标签v-for,我把v-for代码放在<client-only>块中,问题解决了
回答by Dan.faudemer
This error can be really painfull to debug. In order to quickly get the element causing an issue edit node_modules/vue/dist/vue.esm.jsand add the following lines :
这个错误调试起来真的很痛苦。为了快速获取导致问题的元素,请编辑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)
// ...
You will get in the console the failing node.
您将在控制台中获得故障节点。
回答by Michael Cole
See here for an example of how to deal with integrations (e.g. Google Analytics or FB Pixel) that modify the DOM. Basically create a plugin and exclude from SSR.
有关如何处理修改 DOM 的集成(例如 Google Analytics 或 FB Pixel)的示例,请参见此处。基本上创建一个插件并从 SSR 中排除。
回答by Mark Sonn
Ok this is going to sound silly. I tried a bunch of different solutions for about 15 mins such as restarting the server and deleting the .nuxt directory but I was too lazy to use @budden73's big brain solution. What ended up working for me was simply restarting my computer, give it a shot.
好吧,这听起来很傻。我尝试了大约 15 分钟的一系列不同解决方案,例如重新启动服务器并删除 .nuxt 目录,但我懒得使用 @budden73 的大脑解决方案。最终对我有用的只是重新启动我的计算机,试一试。
回答by Noob Coder
What I have found so far from observation is that when you are using third party packages like jQuery (specially), they sometimes inject html tags into the dom. So Vue/Nuxt looses track of the dom tree and starts complaining.
到目前为止,我从观察中发现,当您使用像 jQuery(特别是)这样的第三方包时,它们有时会将 html 标签注入到 dom 中。所以 Vue/Nuxt 失去了对 dom 树的跟踪并开始抱怨。
I was having the same problem and after a while I removed all jQuery and replaced jQuery functionality with Vuejs and those error were all gone.
我遇到了同样的问题,一段时间后我删除了所有 jQuery 并用 Vuejs 替换了 jQuery 功能,这些错误都消失了。

