You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:15:10