一、前言:

做业务的时候我估计大家请求网络的方法调了无数次了,但很少自己去封装一个,刚好最近有个vue3+TypeScript的新坑我负责去搭框架,封装axios请求的时候发现和JS还是有点区别的,所以记录一下。

二、认识axios中的AxiosRequestConfig和AxiosResponse

封装过程中用到了这两个类型,在用vue3项目的小伙伴不知道有没有看到过这行代码。如果看到过你知道AxiosRequestConfig和 AxiosResponse是啥意思不?

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';

在axios中,AxiosRequestConfig 和AxiosResponse 都是一种axios库自带的类型可以直接用也可以自己重写:

AxiosRequestConfig:
用于配置HTTP请求的相关参数。它包含了一系列可配置的选项,用于定制化请求的行为。以下是一些常见的AxiosRequestConfig
选项:

  • url : 发送请求的URL地址。
  • method : 请求使用的HTTP方法(例如GET、POST、PUT、DELETE等)。
  • params : 一个包含键值对的对象,用于作为GET请求的查询参数。
  • data : 要作为POST或PUT请求体发送的数据。
  • headers : 一个包含自定义请求头的对象。
  • timeout : 请求超时时间,单位为毫秒。
  • responseType : 期望在响应中接收的数据类型(例如’json’、‘text’、'blob’等)。

AxiosResponse :
用于表示HTTP请求的响应数据。它包含了请求的响应信息,如状态码、响应头、响应数据等。以下是一些AxiosResponse
接口中常见的属性:

  • data : 响应数据,通常是一个包含服务器响应的数据的对象。
  • status : HTTP状态码,表示请求的结果。
  • statusText : HTTP状态消息,与状态码对应的文本描述。
  • headers : 响应头信息,包含服务器返回的所有响应头。
  • config : 包含发起请求时提供的配置信息的对象。
  • request : 包含关于请求的详细信息的对象。

三、封装完整请求函数和用法说明

(1)封装函数,文件命名为request.ts

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import useStore from '@/store';

// 创建一个 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { 'Content-Type': 'application/json;charset=utf-8' }
});

// 请求拦截器
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    if (!config.headers) {
      throw new Error(
        `好像没有请求头哦`
      );
    }
    // 这里是从vuex或者pinia中拿到token, 并且放到请求头中
    const { user } = useStore();
    if (user.token) {
      config.headers.Authorization = `${window.localStorage.getItem('token')}`;
    }
    return config;
  },
  (error: any) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const { code, msg } = response.data;
    if (code === '00000') {
      return response.data;
    } else {
      // 响应数据为二进制流处理(Excel导出)
      if (response.data instanceof ArrayBuffer) {
        return response;
      }

      ElMessage({
        message: msg || '系统出错',
        type: 'error'
      });
      return Promise.reject(new Error(msg || 'Error'));
    }
  },
  (error: any) => {
    if (error.response.data) {
      const { code, msg } = error.response.data;
      // token 过期,重新登录
      if (code === 'A0999') {
        ElMessageBox.confirm('当前页面已失效,请重新登录', 'Warning', {
          confirmButtonText: 'OK',
          type: 'warning'
        }).then(() => {
          window.localStorage.clear();
          window.location.href = '/';
        });
      } else {
        ElMessage({
          message: msg || '系统出错',
          type: 'error'
        });
      }
    }
    return Promise.reject(error.message);
  }
);

// 导出 axios 实例
export default service;

(2)需要请求某个接口时

写在api.ts文件中

import request from '@/utils/request';

/**
 * 使用添加用户信息接口
 * @param data
 */
export function addUser(data: any) {
  return request({
    url: '/api/index/users',
    method: 'post',
    data: data
  });
}

(3)在业务页面使用addUser接口

import { addUser } from '@/api/user';

/**
 * 提交接口
 */
function saveForm() {
  formRef.value.validate((valid: any) => {
    if (valid) {
        addUser(state.formData).then(() => {
          ElMessage.success('提交成功咯');
        });
      }
  });
}

小结:

从封装到使用的流程都写出来了,应该挺好理解的吧。其实还能封装的更细节的,但怕越写越复杂难懂就点到即止了,例如:

  1. 自己重写一个类型用extends继承AxiosRequestConfig 和AxiosResponse使其在原有基础上更加灵活
  2. 对单个请求对请求config的处理,使每个请求有自己的拦截器,不传就用默认拦截器
  3. 封装到具体的get、post类型,而且不是传过去
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐