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

Nuxt3中用ApiResponse封装useFetch/$fetch响应的方案优化问询

自定义ApiResponse封装useFetch与$fetch的方案优化

一、useFetch中onResponse与transform的执行顺序确认

useFetch的onResponse钩子一定会在transform回调之前执行。
从Nuxt的useFetch实现逻辑来看,它内部调用ofetch完成请求后,会先触发onResponse钩子(此时能拿到完整的Response对象,包含状态码、响应头、原始响应体等),之后才会执行transform回调对响应数据做处理。你查看ofetch源码得到的结论也能印证这一点——ofetch的onResponse是在响应解析(parse)前触发的,而useFetch的transform是基于解析后的数据执行的,所以顺序是确定的。

二、useFetch的封装方案

因为useFetch默认只返回transform处理后的数据,我们可以封装一个自定义的useApiFetch,在onResponse中捕获完整响应信息,再在transform中把这些信息和数据一起封装到ApiResponse类中:

// 自定义封装函数
export function useApiFetch(url, options = {}) {
  // 用于存储完整响应信息
  let responseMeta = null;

  return useFetch(url, {
    ...options,
    onResponse({ response }) {
      // 先执行用户传入的onResponse(如果有)
      options.onResponse?.({ response });
      // 保存响应元数据:状态码、响应头、原始响应
      responseMeta = {
        status: response.status,
        statusText: response.statusText,
        headers: response.headers,
      };
    },
    transform(data) {
      // 执行用户传入的transform(如果有)
      const transformedData = options.transform?.(data) || data;
      // 返回封装后的ApiResponse实例
      return new ApiResponse(transformedData, responseMeta);
    },
  });
}

调用useApiFetch时,返回的data即为ApiResponse实例,可通过它的方法获取数据、状态码等信息。

三、$fetch的封装优化

如果现有方案存在重复代码或不够简洁,推荐做全局实例化封装:

方案:创建预配置的fetch实例

利用ofetch的createFetch创建一个自带封装逻辑的fetch实例,自动将响应转换为ApiResponse:

import { createFetch } from 'ofetch';

export const apiFetch = createFetch({
  baseURL: '/api', // 可根据项目配置基础URL
  async onResponse({ response }) {
    // 直接获取ofetch已解析的响应数据
    const data = response._data;
    // 封装为ApiResponse并返回
    return new ApiResponse(data, {
      status: response.status,
      headers: response.headers,
      statusText: response.statusText,
    });
  },
});

之后直接调用apiFetch('/endpoint'),返回的就是ApiResponse实例,无需每次手动处理响应。

四、进一步改进建议

  • 统一转换逻辑:把ApiResponse的封装逻辑抽成独立函数(如wrapResponse),让useApiFetch和apiFetch共用,减少代码重复。
  • 错误处理整合:在封装中加入统一的HTTP错误捕获,封装为自定义ApiError类,和ApiResponse形成统一返回格式,方便上层处理。
  • 类型支持:为ApiResponse和封装函数添加TypeScript类型定义,提升开发体验。
  • Nuxt全局注册:如果是Nuxt项目,可在plugins中注册封装后的apiFetch,通过useNuxtApp().$apiFetch全局调用,更便捷。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:37:25