Nuxt3中useCustomFetch在onMounted触发时 hydration不匹配问题
问题分析与解决
问题原因
你遇到的Hydration completed but contains mismatches错误,核心是服务端渲染的页面数据和客户端 hydrated 后的页面数据不一致:
- 你的
useCustomFetch里加了if (typeof window === 'undefined') return;,导致服务端执行该函数时直接返回undefined,服务端渲染的页面没有数据; - 刷新页面时,客户端
onMounted触发后执行useCustomFetch会正常获取数据,这就造成服务端渲染的空页面和客户端有数据的页面不匹配,触发 hydration 错误; - 跳转进入页面是客户端路由跳转,没有服务端渲染过程,所以不会出现不匹配;原生
useFetch在 setup 里调用时,Nuxt 会自动在服务端和客户端同步执行,保证数据一致,因此无报错。
解决方案
- 移除
if (typeof window === 'undefined') return;判断,让useCustomFetch在服务端也能正常执行useFetch; - 加载提示逻辑要区分服务端和客户端,因为服务端无法操作浏览器状态;
- 若想预渲染数据,建议直接在 setup 里调用
useCustomFetch,而非onMounted;若必须在onMounted调用,需保证服务端和客户端初始数据状态一致。
修改后的useCustomFetch代码
import { useFetch } from '#app'; export async function useCustomFetch(url: string, options: any, showLoading: boolean = false) { if (!process.server) { console.log("Not Server side called APIs"); if (showLoading) { console.log("Showing loading..."); } } console.log("called APIs"); try { const { data, error } = await useFetch(url, options); if (!process.server && showLoading) { console.log("Closing loading..."); } const responseError = error.value; if (responseError) { console.error("Fetch error: ", responseError); return null; } return data.value; } catch (err) { console.error("Error in useCustomFetch:", err); throw err; } }
页面调用优化示例
如果需要服务端预渲染数据,直接在 setup 中调用:
<script setup> const inventoryData = ref(null); const error = ref(null); const loading = ref(true); try { inventoryData.value = await useCustomFetch('/api/inventory/', { method: 'GET', }, true); } catch (err: any) { error.value = err; } finally { loading.value = false; } </script>
内容的提问来源于stack exchange,提问作者Wong Yat Cheong Jacky
相关产品推荐
相关产品推荐

