二次封装Axios,两个字,优雅!

987 阅读4分钟

前言

我们在前端开发时要发送请求时离不开axios的,但是,如果直接去使用axios每次都需要写很多的重复代码,如地址、url等

今天我就带大家去封装一个优雅的axios,看完你一定会直呼:“太优雅了”

目录结构

image.png

这里一共有三个js文件

分别是axios.js、status.js、userService.js

  1. axios.js:

    • 这个文件是对原始的 axios 库进行了封装和扩展。
    • 这里添加一些全局的配置,如请求和响应的拦截器。
    • 请求拦截器可以用于添加一些公共的请求头,如认证信息。
    • 响应拦截器可以用于统一处理响应结果,如错误处理、loading 状态管理等。
  2. status.js:

    • 这个文件主要用于定义和管理项目中的各种状态码和对应的处理逻辑。
    • 包含状态码到错误消息的映射,以及相应的处理函数。
    • 在 axios.js 的响应拦截器中,可以根据响应的状态码来调用 status.js 中定义的处理函数。
  3. userService.js:

    • 这个文件主要用于定义和管理与用户相关的 API 接口。
    • 包含一些常用的 CRUD 操作,如登录、注册、获取用户信息等。
    • 这个文件可以将具体的 API 请求封装成方法,供其他组件调用时使用。
    • 这样做的好处是将 API 接口的定义和调用逻辑集中管理,提高代码的可维护性。

接下里看以下里面的具体代码,可直接复制使用

axios.js

import axios from "axios";
import { showMessage } from "./status"; // 状态码文件
import { ElMessage } from "element-plus"; 

// 设置接口超时时间
axios.defaults.timeout = 60000;

// 请求地址,这里是动态赋值的的环境变量
// axios.defaults.baseURL = import.meta.env.VITE_API_DOMAIN;
// 非动态
axios.defaults.baseURL = "http://localhost:8000";

//http request 拦截器
axios.interceptors.request.use(
  (config) => {
    // 配置请求头
    config.headers = {
      //'Content-Type':'application/x-www-form-urlencoded',   // 传参方式表单
      "Content-Type": "application/json;charset=UTF-8", // 传参方式json
      token: "80c483d59ca86ad0393cf8a98416e2a1", // 这里自定义配置,这里传的是token
    };
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

//http response 拦截器
axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    const { response } = error;
    if (response) {
      // 请求已发出,但是不在2xx的范围
      showMessage(response.status); // 传入响应码,匹配响应码对应信息
      return Promise.reject(response.data);
    } else {
      ElMessage.warning("网络连接异常,请稍后再试!");
    }
  }
);

// 封装 GET POST 请求并导出
export function request(url = "", params = {}, type = "POST") {
  //设置 url params type 的默认值
  return new Promise((resolve, reject) => {
    let promise;
    if (type.toUpperCase() === "GET") {
      promise = axios({
        url,
        params,
      });
    } else if (type.toUpperCase() === "POST") {
      promise = axios({
        method: "POST",
        url,
        data: params,
      });
    }
    //处理返回
    promise
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

status.js

export const showMessage = (status) => {
  let message = "";
  switch (status) {
    case 400:
      message = "请求错误(400)";
      break;
    case 401:
      message = "未授权,请重新登录(401)";
      break;
    case 403:
      message = "拒绝访问(403)";
      break;
    case 404:
      message = "请求出错(404)";
      break;
    case 408:
      message = "请求超时(408)";
      break;
    case 500:
      message = "服务器错误(500)";
      break;
    case 501:
      message = "服务未实现(501)";
      break;
    case 502:
      message = "网络错误(502)";
      break;
    case 503:
      message = "服务不可用(503)";
      break;
    case 504:
      message = "网络超时(504)";
      break;
    case 505:
      message = "HTTP版本不受支持(505)";
      break;
    default:
      message = `连接出错(${status})!`;
  }
  return `${message},请检查网络或联系管理员!`;
};

userService.js

import { request } from "./axios";

/**
 * @description -封装User类型的接口方法
 */
export default class UserService {
  // 获取验证码
  static async getCode(params) {
    return request("/getCode", params, "post");
  }
  // 员工登录
  static async login(params) {
    return request("/login", params, "post");
  }
  // 员工注册
  static async register(params) {
    return request("/register", params, "post");
  }
  // 管理员登录
  static async loginAdmin(params) {
    return request("/login", params, "post");
  }
  // 管理员注册
  static async registerAdmin(params) {
    return request("/register", params, "post");
  }
  // 获取用户信息
  static async getUserInfo(params) {
    return request("/getUserInfo", params, "post");
  }
}

在axios.js文件里有一段代码

// 请求地址,这里是动态赋值的的环境变量
// axios.defaults.baseURL = import.meta.env.VITE_API_DOMAIN;

这里是基于.env文件去实现动态的绑定URL地址,如希望使用.env的话

.env:守护数据安全的隐形盾牌 - 掘金 (juejin.cn)中有详细介绍其使用方式,欢迎大佬们斧正一下

在userService.js中我们就已经成功的封装好了对应的接口,只需要在文件中引入userService.js后,即可使用里面的方法,直接发送请求,非常的优雅

import UserService from "@/api/userService";

let res = await UserService.login(data);

console.log(res)

后续如果还有其他的模块需要封装接口,就可以同样的创建一个文件,按照userService.js的风格去封装接口

总结

本文详细的介绍了二次封装Axios,结合代码为大家进行讲解,大家可以直接复制我的代码到自己的项目中使用,修改成自己想要的效果,经过封装的axios真的是很优雅,使用起来相当的舒服!!!