[Vue 警告]:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配( Nuxt / Vue / lerna monorepo )

Posted

技术标签:

【中文标题】[Vue 警告]:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配( Nuxt / Vue / lerna monorepo )【英文标题】:[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content ( Nuxt / Vue / lerna monorepo ) 【发布时间】:2020-05-16 12:57:08 【问题描述】:

我正在尝试运行一个基本的 Nuxt 应用程序,其中包含一个使用 lerna monorepo 中的 vue-cli 构建的外部 Vue 组件。

页面短暂显示组件内容(服务器渲染)然后消失并抛出以下错误。

"export 'default' (imported as 'Header') was not found in 'a2b-header'

紧随其后

Mismatching childNodes vs. VNodes: NodeList(7) [svg, text, div#app, text, h2.subtitle, text, div.links] (7) [VNode, VNode, VNode, VNode, VNode, VNode, VNode]

最后是红色的 Vue 警告

[Vue warn]: 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.

我用于外部组件的设置是 package.json


  "name": "a2b-header",
  "version": "0.1.0",
  "private": true,
  "main": "./dist/a2b-header.umd.js",
  "scripts": 
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name a2b-header src/main.js",
    "lint": "vue-cli-service lint"
  ,
  "dependencies": 
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
  ,
  ...

我的 ma​​in.js 如下所示:

import Header from './Header.vue'

export default Header

而组件文件本身Header.vue是:

<template>
  <div id="app">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</template>

<script>
export default 
  name: 'Header'

</script>

<style>
#app 
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;

</style>

所有都被导入 Nuxt 项目 index.vue 使用简单:

import Header from 'a2b-header'

并且....它不起作用。我认为 s-s-r 与客户端的不匹配与不正确的导出有关,可能可以通过一些 webpack 配置解决,但在尝试了许多不同的事情之后,我在这里非常挣扎。

我想让它发挥作用的原因是,我们计划在 monorepo 中拥有各种 Vue 应用程序(SPA 和 Nuxt),并且将通用代码封装在可跨不同项目重用的组件中的能力至关重要。

【问题讨论】:

【参考方案1】:

&lt;ClientOnly&gt; &lt;YourComponent&gt; &lt;/ClientOnly&gt;包装你的组件

请访问官方 nuxt 文档了解更多信息:

https://nuxtjs.org/docs/2.x/features/nuxt-components#the-client-only-component

【讨论】:

【参考方案2】:

经过大量的头部撞击之后,解决方案如下。在nuxt.config.js中,我们需要在扩展函数里面的构建块中添加:

    extend (config, ctx) 
      config.resolve.symlinks = false
    

这个设置最终正确地构建了一个共享包符号链接到 Nuxt 项目 node_modules。导出默认错误已消失,因此所有不匹配的 s-s-r 与 Vnode 警告。

【讨论】:

【参考方案3】:

您可以尝试使用 包装组件,或将所有 dom 操作移至已安装的生命周期挂钩。

https://github.com/nuxt/nuxt.js/issues/1700#issuecomment-331099596

这个answer 可以帮助你

【讨论】:

感谢您的回复!我不想使用 no-s-s-r,因为该组件应该在服务器上正确呈现,它不会引用 DOM 和零操作。 我也尝试过堆栈跟踪检查,很奇怪...但是 elm 和 vnode.elm 是相同的。

以上是关于[Vue 警告]:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配( Nuxt / Vue / lerna monorepo )的主要内容,如果未能解决你的问题,请参考以下文章

Nuxt.js 错误:客户端渲染的虚拟 DOM 树与服务器渲染的内容不匹配

Vue中的浏览器关键渲染路径及虚拟DOM

在 Vue 中使用 s-s-r 时在哪里调用“Vue.use(plugin)”

nuxt项目中vue报错The client-side rendered virtual ...

vue项目改造SSR(服务端渲染)

vue渲染虚拟dom树原理