如何打造优雅、高效的前端axios请求

  1. 包安装
shell 复制代码
npm install axios
  1. 创建 Axios 实例

在项目 src 目录下创建 api 文件夹,并在其中创建 axios.ts 文件:

ts 复制代码
import axios, { AxiosRequestConfig, AxiosResponse, AxiosInstance, AxiosPromise } from 'axios';  
import { ElNotification } from 'element-plus';  
  
// 创建 Axios 实例  
const instance: AxiosInstance = axios.create({  
  baseURL: import.meta.env.VITE_APP_BASE_API, // 基础路径  
  timeout: 10000, // 超时时间  
});  
  
// 请求拦截器  
instance.interceptors.request.use(  
  (config: AxiosRequestConfig) => {  
    // 请求拦截逻辑,如根据 env 设置不同环境的 token 等  
    return config;  
  },  
  (error) => Promise.reject(error)  
);  
  
// 响应拦截器  
instance.interceptors.response.use(  
  (response: AxiosResponse) => {  
    // 成功时处理逻辑  
    const { code, data, msg } = response.data;  
    if (code === 200) {  
      return Promise.resolve(data);  
    } else if (code === 401) {  
      ElNotification({ type: 'error', message: '登录过期,请重新登录' });  
      return Promise.reject(msg);  
    } else {  
      ElNotification({ type: 'error', message: msg });  
      return Promise.reject(msg);  
    }  
  },  
  (error: AxiosError) => {  
    // 错误时处理逻辑  
    let msg = '';  
    const status = error.response?.status;  
    switch (status) {  
      case 401:  
        msg = '登录过期,请重新登录';  
        break;  
      case 403:  
        msg = '拒绝访问';  
        break;  
      case 404:  
        msg = `请求地址出错: ${error.response?.config?.url}`;  
        break;  
      case 500:  
        msg = '服务器内部错误';  
        break;  
      case 502:  
        msg = '网关错误';  
        break;  
      case 503:  
        msg = '服务不可用';  
        break;  
      case 504:  
        msg = '网关超时';  
        break;  
      default:  
        msg = error.message;  
    }  
    ElNotification({ type: 'error', message: msg });  
    return Promise.reject(error);  
  }  
);  
  
// 请求方法  
instance.all = axios.all;  
instance.spread = axios.spread;  
instance.Axios = axios.Axios;  
  
export default instance;

3. 接口地址封装

src/api 目录下创建 api.ts 文件,对接口地址进行封装:

ts 复制代码
// 示例接口配置  
const api = {  
  users: {  
    get: () => `/api/v1/users`,  
    post: () => `/api/v1/user`,  
    put: (id: string) => `/api/v1/user/${id}`,  
    delete: (id: string) => `/api/v1/user/${id}`,  
    getDetail: (id: string) => `/api/v1/user/${id}`,  
  },  
};  
  
export default api;

4. 封装请求方法

src/api 下创建 apiInterceptor.ts 文件,封装请求和响应处理:

ts 复制代码
import instance from './axios';  
import api from './api';  
  
interface AxiosRequestFn<T> {  
  (options?: any): AxiosPromise<T>;  
}  
  
export const get = <T>(url: string, params?: any): AxiosPromise<T> => {  
  return instance.get<T>(url, { params });  
};  
  
export const post = <T>(url: string, data?: any): AxiosPromise<T> => {  
  return instance.post<T>(url, data);  
};  
  
export const put = <T>(url: string, data?: any): AxiosPromise<T> => {  
  return instance.put<T>(url, data);  
};  
  
export const del = <T>(url: string, data?: any): AxiosPromise<T> => {  
  return instance.delete<T>(url, { data });  
};  
  
export function getUsers<T>(page = 1, pageSize = 10): AxiosPromise<T> {  
  return get<T>(api.users.get(), { page, pageSize });  
}  
  
export function addUser<T>(data: any): AxiosPromise<T> {  
  return post<T>(api.users.post(), data);  
}  
  
export function getUserDetail<T>(id: string): AxiosPromise<T> {  
  return get<T>(api.users.getDetail(id));  
}  
  
export function updateUser<T>(id: string, data: any): AxiosPromise<T> {  
  return put<T>(api.users.put(id), data);  
}  
  
export function deleteUser<T>(id: string, data?: any): AxiosPromise<T> {  
  return del<T>(api.users.delete(id), data);  
}

5. 在组件中使用

在 Vue 组件中调用封装后的请求方法:

ts 复制代码
<template>
  <div>
    <el-table :data="tableData" stripe style="width: 100%">
      <el-table-column prop="name" label="姓名" width="180" />
      <el-table-column prop="address" label="地址" />
    </el-table>
  </div>
</template>

<script setup lang="ts">
import { getUsers } from '@/api/apiInterceptor';

const tableData = ref([]);

// 获取用户列表
const getUserList = async () => {
  try {
    const res = await getUsers();
    tableData.value = res;
  } catch (err) {
    console.error('获取用户列表失败:', err);
  }
};

onMounted(() => {
  getUserList();
});
</script>
相关推荐
EndingCoder4 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架
后海 0_o9 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
喵叔哟10 小时前
24.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--认证微服务
微服务·架构·.net
java干货10 小时前
虚拟线程与消息队列:Spring Boot 3.5 中异步架构的演进与选择
spring boot·后端·架构
SoFlu软件机器人10 小时前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
西陵11 小时前
前端框架渲染DOM的的方式你知道多少?
前端·javascript·架构
hsg7714 小时前
基于nacos2.5.1的MCP服务端微服务项目开发环境配置简介
微服务·云原生·架构
DemonAvenger15 小时前
减少内存分配:Go中值类型与指针类型的选择
性能优化·架构·go
xzh15 小时前
问题:Nginx client_body_temp_path 文件会删除吗,删除时机?
nginx·架构
hstar952716 小时前
三十三、面向对象底层逻辑-SpringMVC九大组件之HandlerExceptionResolver接口设计
java·spring·设计模式·架构