如何打造优雅、高效的前端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>
相关推荐
JMchen1231 小时前
现代Android图像处理管道:从CameraX到OpenGL的60fps实时滤镜架构
android·图像处理·架构·kotlin·android studio·opengl·camerax
Jing_jing_X4 小时前
CPU 架构:x86、x64、ARM 到底是什么?为什么程序不能通用?
arm开发·架构·cpu
qq_177767376 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体
小程故事多_807 小时前
深度搜索Agent架构全解析:从入门到进阶,解锁复杂问题求解密码
人工智能·架构·aigc
●VON8 小时前
React Native for OpenHarmony:项目目录结构与跨平台构建流程详解
javascript·学习·react native·react.js·架构·跨平台·von
Gary董8 小时前
高并发的微服务架构如何设计
微服务·云原生·架构
ujainu8 小时前
Flutter + OpenHarmony 实战:《圆环跳跃》——完整游戏架构与视觉优化
flutter·游戏·架构·openharmony
爬山算法9 小时前
Hibernate(74)如何在CQRS架构中使用Hibernate?
java·架构·hibernate
香芋Yu9 小时前
【大模型教程——第二部分:Transformer架构揭秘】第2章:模型家族谱系:从编码器到解码器 (Model Architectures)
深度学习·架构·transformer
从此不归路11 小时前
Qt5 进阶【13】桌面 Qt 项目架构设计:从 MVC/MVVM 到模块划分
开发语言·c++·qt·架构·mvc