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

Nuxt3非组合式组件多useFetch调用异常求助

问题

我用非组合式(选项式API)编写Nuxt3组件,不想重构。为避免客户端与服务端重复请求,选择用useFetch而非$fetch。仅调用一次useFetch并通过.data.value取值时一切正常,但添加第二个useFetch调用后,出现错误:[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook,etc。

正常运行代码

export default {
  async serverPrefetch() {
    const store = useDataStore()
    await this.fetchData(store);
  },
  mounted() {
    const store = useDataStore()
    this.fetchData(store);
  },
  methods: {
    async fetchData(store) {
      const yesterdayBevData = await useFetch('/api/yesterdayBevs')
      store.setYesterdayBevs(yesterdayBevData.data.value)

      const bevData = await $fetch('/api/getBevSection/1')
      
      store.setBevModels(bevData)
    },
  }
}

异常代码(将一处$fetch替换为useFetch)

export default {
  async serverPrefetch() {
    const store = useDataStore()
    await this.fetchData(store);
  },
  mounted() {
    const store = useDataStore()
    this.fetchData(store);
  },
  methods: {
    async fetchData(store) {
      const yesterdayBevData = await useFetch('/api/yesterdayBevs')
      store.setYesterdayBevs(yesterdayBevData.data.value)

      const bevData = await useFetch('/api/getBevSection/1')
      
      store.setBevModels(bevData.data.value)
    },
  }
}

我尝试用runWithContext包裹每个useFetch调用,错误消失,但第二个请求在客户端出现了不必要的重复请求:

const nuxtApp = useNuxtApp()
const bevData = await nuxtApp.runWithContext(() => useFetch('/api/getBevSection/'+key))
const yesterdayBevData = await nuxtApp.runWithContext(() => useFetch('/api/yesterdayBevs'))

store.setYesterdayBevs(yesterdayBevData.data.value)
store.setBevModels(bevData.data.value.bev)

请问如何实现在非组合式组件中发起多个请求,同时避免客户端重复请求?


解决方案

核心问题原因

  1. 选项式API的methods不在Nuxt的组合式上下文范围内,直接在methods中调用多个useFetch会触发上下文缺失错误。
  2. 单独用runWithContext包裹每个useFetch,会破坏Nuxt内置的请求缓存与服务端数据hydration机制,导致客户端无法复用服务端已获取的数据,从而重复请求。

正确实现方式

将数据获取逻辑放在setup函数中(处于Nuxt组合式上下文),再在serverPrefetch和mounted中调用该逻辑,同时在客户端判断数据是否已存在,避免重复请求:

export default {
  setup() {
    const store = useDataStore()
    
    // 定义在组合式上下文内的数据获取函数
    const fetchData = async () => {
      // useFetch会自动处理服务端缓存与客户端hydration
      const yesterdayBevRes = await useFetch('/api/yesterdayBevs')
      store.setYesterdayBevs(yesterdayBevRes.data.value)

      const bevRes = await useFetch('/api/getBevSection/1')
      store.setBevModels(bevRes.data.value)
    }

    return { fetchData }
  },
  // 服务端预获取数据
  async serverPrefetch() {
    await this.fetchData()
  },
  // 客户端仅在数据缺失时请求
  async mounted() {
    const { yesterdayBevs, bevModels } = useDataStore()
    if (!yesterdayBevs || !bevModels) {
      await this.fetchData()
    }
  }
}

关键说明

  • setup函数是Nuxt组合式上下文的入口,在此处调用useFetch能保证上下文正确,不会触发错误。
  • useFetch内置了服务端数据序列化与客户端复用逻辑,只要在同一上下文内调用,客户端会自动复用服务端已获取的数据,无需额外处理。
  • 在mounted中判断数据是否存在,避免服务端已预取数据后,客户端再次发起重复请求。

内容的提问来源于stack exchange,提问作者Michail Michailidis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:56:30