nuxt3服务端与客户端渲染不一致-案例

环境

makefile 复制代码
node: v20.12.2,
"nuxt": "^3.11.2",
"vue": "^3.4.27",

所有案例均基于 nuxt3

随机数

html 复制代码
<template>
  <div>
    <h3>nuxt3 渲染上的不一致</h3>

    <div>
      <div v-for="item in colors">{{ item }}</div>
    </div>
  </div>
</template>

<script setup>
const colors = ref([]);

function generateRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

for (let i = 0; i < 5; i++) {
  colors.value.push(generateRandomColor());
}
</script>

看代码上没问题,放 SPA里面 也不会有任何问题,但是放nuxt3/SSR框架里面,就会出现 服务端渲染和客户端渲染不一致问题

scss 复制代码
Hydration text content mismatch on  (水合不匹配)

... 某一个组件

- rendered on server: #047FC3   服务端渲染,得到的第一项的值是 #047FC3
- expected on client: #1E87BA   客户端的时候,重新运行,变成了 #1E87BA

造成了,服务端和客户端渲染内容不一致, nuxt3 会以 客户端渲染为主, 所以我们看到的结果是: #1E87BA

解决办法:

  1. 将数据定死,就N个, 不管页面如何刷新 colors 始终是那些数据
js 复制代码
const colors = ref([
    "xxxx",
    "1111"
])
  1. server中取数据
html 复制代码
<template>
  <div>
    <h3>nuxt3 渲染上的不一致</h3>

    <div>
      <div v-for="item in colors">{{ item }}</div>
    </div>
  </div>
</template>

<script setup>
const colors = ref([]);

const res = await useFetch('/api/getColors')

colors.value = res.data.value
</script>

server/api/getColors.ts

js 复制代码
function generateRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

export default defineEventHandler(() => {
  let list = []

  for (let i = 0; i < 5; i++) {
    list.push(generateRandomColor());
  }

  return list
})

network 中看这个页面的字符串内容,从 api 接口中取值,是都拼接好了结果的。

  1. 将取数的逻辑放在 onMounted 里面 从 客户端去取数据,填充数据,这样就不会造成服务端与客户端生成的结果不一致的警告
html 复制代码
<template>
  <div>
    <h3>nuxt3 渲染上的不一致</h3>

    <div>
      <div v-for="item in colors">{{ item }}</div>
    </div>
  </div>
</template>

<script setup>
const colors = ref([]);

function generateRandomColor() {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

onMounted(() => {
  for (let i = 0; i < 5; i++) {
    colors.value.push(generateRandomColor());
  }
});
</script>
相关推荐
拉不动的猪几秒前
浏览器&Websocket&热更新
前端·javascript·vue.js
那些免费的砖10 分钟前
Reka UI - 一款免费开源的 Vue 无头 UI 组件库,样式定制开发项目的绝佳选择
vue.js·ui·开源
前端付豪1 小时前
Vue 中的 JSX:让组件渲染更灵活的正确方式
前端·javascript·vue.js
apollo_qwe2 小时前
Vue 权限控制神技!自定义 auth 指令优雅实现按钮级权限管理
vue.js·架构
阿登林3 小时前
Vue面试项目经验分享:如何专业展示技术能力与解决问题
vue.js·经验分享·面试
黄交大彭于晏3 小时前
UniApp 全局通知功能实现
前端·vue.js·uni-app
一 乐3 小时前
流浪动物救助|流浪猫狗救助|基于Springboot+vue的流浪猫狗救助平台设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设
国思RDIF框架3 小时前
国思RDIF低代码快速开发框架 v6.2.2版本发布
前端·vue.js·后端
小高0073 小时前
深入理解 package.json:前端项目的 "身份证"
前端·javascript·vue.js
修罗-zero4 小时前
vue在获取某一个div的大小,怎么确保div渲染好,内容撑开后才去获取大小
前端·javascript·vue.js