vue3+TypeScript+axios封装一个网络请求函数,拿了就能用

一、前言:

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

二、认识axios中的AxiosRequestConfig和AxiosResponse

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

javascript 复制代码
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';

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

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

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

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

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

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

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

typescript 复制代码
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文件中

php 复制代码
import request from '@/utils/request';

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

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

javascript 复制代码
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类型,而且不是传过去

相关推荐
我命由我1234518 分钟前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳1 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
小大宇2 小时前
Vue知识点-ElementPlus-06 单选+多选+下拉+日期选择
前端·vue.js·elementui
paopaokaka_luck2 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩3 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper3 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js3 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
Nymph_Zhu3 小时前
vue3+element-plus 文件上传
前端·typescript·vue3·element-plus
系统集成-鹰翔3 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
QianhangQianping3 小时前
撤销重做不是「存快照」:一个可视化编辑器的Operation 设计
java·前端·数据库·typescript·编辑器·前端架构·撤销重做