封装Nuxt的useFetch为useCustomFetch后,无await时丢失响应式?
问题原因
你的useCustomFetch被定义成了async函数,调用它会返回一个Promise对象,而非直接返回useFetch提供的响应式data/pending/status对象。当你不使用await直接解构时,实际是在解构Promise的属性,自然无法获取预期的响应式值,UI也就不会自动更新。
解决方案
不要让整个composable变成async,而是将获取认证token的逻辑移到useFetch配置的headers工厂函数中——useFetch支持headers作为异步函数,Nuxt会自动处理这个异步逻辑,同时保持返回的响应式对象特性。
修改后的封装代码:
import type { UseFetchOptions } from 'nuxt/app' import { defu } from 'defu' export function useCustomFetch<T>(url: string, options: UseFetchOptions<T> = {}) { const config = useRuntimeConfig() const { data: authData, status: authStatus, getSession } = useAuth() const defaults: UseFetchOptions<T> = { baseURL: config.public.baseApiUrl, // 将headers改为异步工厂函数 async headers() { const headers: HeadersInit = {} // 访问响应式数据的.value属性获取最新值 if (authData.value && authStatus.value === 'authenticated') { const session = await getSession({ required: true }) headers.Authorization = `Bearer ${session.accessToken}` } return headers }, onResponse(_ctx) { // 自定义响应处理逻辑 }, onResponseError(_ctx) { // 自定义错误处理逻辑 }, } const params = defu(options, defaults) return useFetch(url, params) }
改动说明
- 移除了整个composable的
async标记,确保它直接返回useFetch的响应式对象,和原生useFetch的使用逻辑完全一致。 - 将headers设置为异步函数,既可以异步获取session,又能利用Nuxt对
useFetch配置的异步支持,不会破坏响应式链路。 - 访问
authData.value和authStatus.value(响应式ref必须通过.value获取值),确保能拿到最新的认证状态。
现在组件中原来的写法就能正常响应式更新了:
<script setup> const { data, pending, status } = useCustomFetch('/resources') </script>
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

