Nuxt3中$fetch为何不缓存数据?适配场景技术问询
Nuxt3数据获取工具的缓存差异与场景适配
一、缓存差异的原因
useFetch和useAsyncData是Nuxt专为页面/组件渲染流程设计的组合式函数,它们内置了和Nuxt状态系统、路由导航绑定的缓存机制。在服务端渲染、客户端页面切换时,会自动基于请求key缓存数据,既能避免重复请求,还能把服务端缓存的数据同步到客户端,优化加载体验。$fetch本质是封装了原生Fetch的通用HTTP请求工具,和普通请求库(比如axios)定位一致,没有和Nuxt的生命周期、状态管理绑定,所以默认不带缓存逻辑,每次调用都会发起全新请求。
二、弹窗加载详情的场景解决方案
针对你提到的“点击测试项加载弹窗详情,需要缓存但useFetch的pending状态在事件里不生效”的问题,有两种可行方案:
方案1:给$fetch手动添加缓存逻辑
自己维护一个缓存对象,点击时先检查缓存,无数据再发起请求并存入缓存:
const detailCache = ref({}) const modalData = ref(null) const modalVisible = ref(false) const showDetail = async (testId) => { // 先查缓存 if (detailCache.value[testId]) { modalData.value = detailCache.value[testId] modalVisible.value = true return } // 无缓存则请求 try { const data = await $fetch(`/api/tests/${testId}`) detailCache.value[testId] = data modalData.value = data modalVisible.value = true } catch (err) { // 处理请求错误 console.error('加载详情失败', err) } }
方案2:用useAsyncData手动触发请求
利用useAsyncData的内置缓存,通过immediate: false关闭自动请求,在点击事件里手动触发,同时pending状态可正常使用:
const testId = ref(null) const modalVisible = ref(false) const { data: detailData, pending, refresh } = useAsyncData( // 动态生成缓存key,确保不同测试项的缓存独立 () => `test-detail-${testId.value}`, () => $fetch(`/api/tests/${testId.value}`), { immediate: false } // 初始不自动执行请求 ) const showDetail = async (id) => { testId.value = id // 手动触发请求,同时等待请求完成 await refresh() modalVisible.value = true }
在弹窗里可以直接用pending来显示加载状态,比如:
<Modal v-model="modalVisible"> <div v-if="pending">加载中...</div> <div v-else v-for="item in detailData?.questions" :key="item.id"> <!-- 渲染题目详情 --> </div> </Modal>
内容的提问来源于stack exchange,提问作者Kromel
相关产品推荐
相关产品推荐

