v-if 破坏 nuxt ssr

v-if breaks nuxt ssr

如果我在 v-if 中使用从 apollo 获取的数据 (fetchPolicy: 'cache-and-network'),它会抛出 vue.runtime.esm.js:619 [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.

<template>
  <div
    <div v-if="test">
      {{ test }}
    </div>
  </div>
</template>

但如果我将它用作变量来渲染它就可以正常工作。

<template>
  <div>
    {{ test }}
  </div>
</template>

实际使用的数据是对象,我需要有条件地渲染并使用 v-if 传递给另一个组件。

我曾尝试通过 get 获取数据,监视数据并手动设置它们,但最终一切都崩溃了。

关于评论: 如果我控制 test 数据,它将去 -> 服务器上的 true -> 客户端上的 false 然后 true 再次在客户端上,如果我删除 testv-if 开始:服务器上 true 客户端 true

这与结构无关,在实际项目中它有一堆组件,如果数据不在条件下使用它就可以正常工作

您试图使组件的根元素有条件地消失,这会在虚拟 DOM 中造成不一致。

你能试试吗:

<template>
  <div>
    <template v-if="test">
      {{ test }}
    </template>
  </div>
</template>

SSR 有时很难调试,此类问题经常发生。

https://ssr.vuejs.org/#why-ssr

some external libraries may need special treatment to be able to run in a server-rendered app.

这可能就是重点。一些 vue-components 不能通过开箱即用的 SSR 运行。这就是为什么我从服务器询问内容的原因。

因此,最简单的解决方法可能是用 <no-ssr> 标记包装您的组件。您可以分别对每个组件执行此操作,以找出导致问题的原因。 隔离组件后,您可以在其上保留 <no-ssr> 标记并将其功能迁移到客户端组件的安装区域。

对于遇到相同问题的任何人,我已通过在安装后设置 cache-and-network 来修复它,并且一切正常。

mounted() {
  this.$apollo.queries.getCampaign.setOptions({
    fetchPolicy: 'cache-and-network',
  })
}

根据我的经验,如果你使用 v-if,nuxt 将在 SSR 中失败,除非你包裹在 <no-ssr><client-only>

如果是小组件也可以用v-show代替。