基于TypeScript封装 `axios` 请求工具详解

打印 上一主题 下一主题

主题 849|帖子 849|积分 2547

TypeScript 项目中,封装一个详细的 axios 请求工具可以进步代码的可维护性、可重用性,并让请求逻辑与业务逻辑分离。以下是一个详细的封装示例,包罗请求拦截器、相应拦截器、错误处置惩罚、以及类型定义。
1. 安装 Axios

首先,确保你已安装 axios 和 axios 类型定义。
  1. npm install axios
  2. npm install --save-dev @types/axios
复制代码
2. 封装 Axios 请求工具

在项目中创建一个新的文件 src/utils/axios.ts 来封装所有请求相关的逻辑。
  1. // src/utils/axios.ts
  2. import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
  3. // 定义通用的返回数据结构
  4. interface ApiResponse<T = any> {
  5.   code: number;
  6.   message: string;
  7.   data: T;
  8. }
  9. class AxiosRequest {
  10.   private axiosInstance: AxiosInstance;
  11.   constructor() {
  12.     this.axiosInstance = axios.create({
  13.       baseURL: import.meta.env.VITE_API_BASE_URL,  // 基础URL,可以在环境变量中配置
  14.       timeout: 5000, // 请求超时
  15.       headers: {
  16.         'Content-Type': 'application/json',
  17.       },
  18.     });
  19.     // 请求拦截器
  20.     this.axiosInstance.interceptors.request.use(
  21.       (config: AxiosRequestConfig) => {
  22.         // 可以在请求前做一些操作,例如加入 token
  23.         const token = localStorage.getItem('token');
  24.         if (token) {
  25.           config.headers['Authorization'] = `Bearer ${token}`;
  26.         }
  27.         return config;
  28.       },
  29.       (error: AxiosError) => {
  30.         return Promise.reject(error);
  31.       }
  32.     );
  33.     // 响应拦截器
  34.     this.axiosInstance.interceptors.response.use(
  35.       (response: AxiosResponse<ApiResponse>) => {
  36.         // 可以处理一些通用的响应数据
  37.         const { code, message, data } = response.data;
  38.         if (code === 0) {
  39.           return data;  // 返回正常数据
  40.         } else {
  41.           // 根据不同的 `code` 进行错误处理
  42.           return Promise.reject(new Error(message || '未知错误'));
  43.         }
  44.       },
  45.       (error: AxiosError) => {
  46.         // 统一错误处理
  47.         let errorMessage = '请求失败';
  48.         if (error.response) {
  49.           errorMessage = error.response.data.message || '服务器异常';
  50.         } else if (error.request) {
  51.           errorMessage = '网络异常';
  52.         } else {
  53.           errorMessage = error.message;
  54.         }
  55.         return Promise.reject(new Error(errorMessage));
  56.       }
  57.     );
  58.   }
  59.   // 封装 GET 请求
  60.   public get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
  61.     return this.axiosInstance
  62.       .get<ApiResponse<T>>(url, config)
  63.       .then((response) => response);
  64.   }
  65.   // 封装 POST 请求
  66.   public post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  67.     return this.axiosInstance
  68.       .post<ApiResponse<T>>(url, data, config)
  69.       .then((response) => response);
  70.   }
  71.   // 封装 PUT 请求
  72.   public put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
  73.     return this.axiosInstance
  74.       .put<ApiResponse<T>>(url, data, config)
  75.       .then((response) => response);
  76.   }
  77.   // 封装 DELETE 请求
  78.   public delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
  79.     return this.axiosInstance
  80.       .delete<ApiResponse<T>>(url, config)
  81.       .then((response) => response);
  82.   }
  83. }
  84. // 创建一个 AxiosRequest 实例
  85. const axiosRequest = new AxiosRequest();
  86. export default axiosRequest;
复制代码
3. 请求利用示例

在 Vue 组件中,可以直接导入并利用封装好的请求工具。
  1. // src/views/Example.vue
  2. <template>
  3.   <div>
  4.     <button @click="fetchData">获取数据</button>
  5.     <div v-if="error" class="error">{{ error }}</div>
  6.     <div v-if="data">
  7.       <pre>{{ data }}</pre>
  8.     </div>
  9.   </div>
  10. </template>
  11. <script lang="ts">
  12. import { defineComponent, ref } from 'vue';
  13. import axiosRequest from '@/utils/axios';
  14. export default defineComponent({
  15.   name: 'Example',
  16.   setup() {
  17.     const data = ref<any>(null);
  18.     const error = ref<string>('');
  19.     const fetchData = async () => {
  20.       try {
  21.         const response = await axiosRequest.get('/api/endpoint');  // 调用 GET 请求
  22.         data.value = response;
  23.       } catch (err) {
  24.         error.value = (err as Error).message;
  25.       }
  26.     };
  27.     return {
  28.       data,
  29.       error,
  30.       fetchData,
  31.     };
  32.   },
  33. });
  34. </script>
  35. <style scoped>
  36. .error {
  37.   color: red;
  38. }
  39. </style>
复制代码
4. 设置环境变量

确保在 .env 文件中设置基础的 API URL:
  1. VITE_API_BASE_URL=https://your-api-url.com
复制代码
5. 代码解释



  • 请求拦截器:在请求发送之前,可以为请求添加授权信息(如 token)。也可以处置惩罚其他全局请求设置。
  • 相应拦截器:所有的相应数据都会经过拦截器处置惩罚,统一检查返回的 code,如果为 0 表示乐成,否则会抛出错误。
  • 错误处置惩罚:无论是请求错误还是相应错误,都会被统一捕捉并返回可读的错误信息。
  • 请求方法封装:提供了 GET、POST、PUT 和 DELETE 方法封装,可以在不同的接口请求中利用。
通过这种方式,你的 Axios 请求将更加模块化、易于维护,并且在遇到题目时可以或许快速定位和处置惩罚错误。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表