如何打造优雅、高效的前端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>
相关推荐
蒙奇D索大15 分钟前
【操作系统】408操作系统核心考点精讲:宏内核、微内核与外核架构全解析
笔记·考研·架构·改行学it
ACGkaka_1 小时前
DDD(一)认识领域驱动设计(DDD的概念、主要架构模型)
java·微服务·架构
迎風吹頭髮11 小时前
Linux内核架构浅谈49-Linux per-CPU页面缓存:热页与冷页的管理与调度优化
linux·缓存·架构
云创智城-yuncitys12 小时前
SpringCloud 架构在智慧交通路侧停车系统中的实践:从技术落地到城市级服务升级
spring·spring cloud·架构·智慧城市·停车系统·充电系统源码
2202_7557443012 小时前
外贸独立站SEO技术架构深度优化指南
架构·cdn分布式架构
墨利昂14 小时前
Transformer架构:深度学习序列建模的革命性突破
深度学习·架构·transformer
lpfasd12315 小时前
第2部分:Netty核心架构与原理解析
运维·服务器·架构
王嘉祥17 小时前
Pangolin:基于零信任理念的反向代理
后端·架构
brzhang20 小时前
Node 服务遇到血崩,汤过坑才知道,限流与熔断是你绕不过的坑
前端·后端·架构