【nuxt】Hydration completed but contains mismatches
【nuxt】Hydration completed but contains mismatches
nuxt项目部署到线上是报错:Hydration completed but contains mismatches(水合作用已完成,但存在不匹配之处),请求接口出现蒙版转圈问题。
问题出现的主要原因:服务器上生成 HTML(SSR)后,在浏览器中“激活”(Hydration)时,Vue 发现客户端渲染的 DOM 结构与服务端返回的 HTML 不匹配。出于安全考虑,Vue/Nuxt 会丢弃服务端渲染的结构并重新渲染,这个过程可能导致页面短暂白屏或“转圈”。

1.模拟线上环境本地调用:npm run preview

ps:需注意不要直接单击链接打开,它只是在告诉你服务器正在本机的所有网络接口上监听 3000 端口。
可以用使用http://localhost:3000,http://127.0.0.1:3000(localhost 的 IPv4 形式),http://[::1]:3000(localhost 的 IPv6 形式),http://192.168.1.100:3000(本地ip加上端口号,其他设备可以访问)。
1.首先排查了依赖版本问题,删除package-lock.json文件和node_modules,重新下载依赖。此时,进入不转圈,通过点击进入页面,正常展示数据,刷新之后就数据就不展示了。
2.分析原因:刷新页面和点击导航的行为不同导致了不同的渲染流程,刷新页面是浏览器向服务器请求完整的 HTML(SSR 结果),点击导航走的是客户端路由不会触发 SSR。
3.检查异步请求代码:
export const useRequestSSR = async (
method: "get" | "post",
url: string,
params: MyObject = {},
initValue: any = {},
watch = true
) => {
const date = new Date();
const dataKey = `${url};${JSON.stringify(params)};${date
.toISOString()
.slice(0, 10)}-${date.getHours()}`;
const result = await useAsyncData(dataKey, () => http[method](url, params), {
default: () => {
return initValue;
},
watch: isReactive(params) && watch ? [params] : [],
});
// debug
if (import.meta.dev && import.meta.client) {
console.log(`AsyncData ${dataKey}`, result.data.value);
}
return result;
};
dataKey包含时间戳,可能会导致SSR 和 CSR 阶段的 dataKey可能不同,这会触发重复请求,且 SSR 和 CSR 可能使用不同的缓存数据,引发 hydration 错误。可以移除时间戳,仅用 url和 params生成唯一键。
修改代码如下:
export const useRequestSSR = async (
method: "get" | "post",
url: string,
params: MyObject = {},
initValue: any = {},
watch = true
) => {
const dataKey = `${url};${JSON.stringify(params)}`;
const result = await useAsyncData(dataKey, () => http[method](url, params), {
default: () => {
return initValue;
},
watch: isReactive(params) && watch ? [params] : [],
});
// debug
if (import.meta.dev && import.meta.client) {
console.log(`AsyncData ${dataKey}`, result.data.value);
}
return result;
};
修改了之后页面可以正常渲染。
更多推荐


所有评论(0)