vue3.0 axios封装

本文介绍了在Vue3.0环境中如何进行axios的封装,包括新建request.ts和server.ts文件,以及设置具体请求服务和全局拦截器,确保请求的高效和统一管理。同时,文章提到了组件库element-plus的ElMessage和ElLoading在请求过程中的应用。
摘要由CSDN通过智能技术生成

环境: 使用vue3.0 及 axios,组件库使用element-plus的 ElMessage及ElLoading

新建request.ts文件,专用于封装axios

import axios, {
    AxiosResponse } from 'axios'
import type {
    AxiosInstance, AxiosRequestConfig } from 'axios'
import type {
   
  RequestConfig,
  RequestInterceptors,
  CancelRequestSource,
} from './types'
import {
    ElMessage, ElLoading } from "element-plus";
let loadingInstance: any;
const startLoading = () => {
   
  loadingInstance = ElLoading.service({
   
    lock: true,
    text: '加载中……',
    background: 'rgba(0, 0, 0, 0.7)'
  });
};
function endLoading() {
   
  loadingInstance.close();
}
class Request {
   
  // axios 实例
  instance: AxiosInstance
  // 拦截器对象
  interceptorsObj?: RequestInterceptors<AxiosResponse>

  /*
  存放取消方法的集合
  * 在创建请求后将取消请求方法 push 到该集合中
  * 封装一个方法,可以取消请求,传入 url: string|string[]  
  * 在请求之前判断同一URL是否存在,如果存在就取消请求
  */
  cancelRequestSourceList?: CancelRequestSource[]
  /*
  存放所有请求URL的集合
  * 请求之前需要将url push到该集合中
  * 请求完毕后将url从集合中删除
  * 添加在发送请求之前完成,删除在响应之后删除
  */
  requestUrlList?: string[]

  constructor(config: RequestConfig) {
   
    this.requestUrlList = []
    this.cancelRequestSourceList = []
    this.instance = axios.create(config)
    this.interceptorsObj = config.interceptors
    // 拦截器执行顺序 接口请求 -> 实例请求 -> 全局请求 -> 实例响应 -> 全局响应 -> 接口响应
    this.instance.interceptors.request.use(
      (res: AxiosRequestConfig) => res,
      (err: any) => err,
    )

    // 使用实例拦截器
    this.instance.interceptors.request.use(
      this.interceptorsObj?.requestInterceptors,
      this.interceptorsObj?.requestInterceptorsCatch,
    )
    this.instance.interceptors.response.use(
      this.interceptorsObj?.responseInterceptors,
      this.interceptorsObj?.responseInterceptorsCatch,
    )
    // 全局响应拦截器保证最后执行
    this.instance.interceptors.response.use(
      // 因为我们接口的数据都在res.data下,所以我们直接返回res.data
      (res: AxiosResponse) => {
   
        if(res.data.code == 200) {
   
          ElMessage({
   
            message: res.data.message,
            grouping: true,
            type: 'success',
          })
          return res.data
        } else {
   
          ElMessage.error(res.data)
          return res.data
        }
      },
      (err: any) => err,
    )
  }
  /**
   * @description: 获取指定 url 在 cancelRequestSourceList 中的索引
   * @param {string} url
   * @returns {number} 索引位置
   */
  private getSourceIndex(url: string): number {
   
    return this.cancelRequestSourceList?.findIndex(
      (item: CancelRequestSource) => {
   
        return Object.keys(item)[0] === url
      },
    ) as number
  }
  /**
   * @description: 删除 requestUrlList 和 cancelRequestSourceList
   * @param {string} url
   * @returns {*}
   */
  private delUrl(url: string) {
   
    const urlIndex = this.requestUrlList?.findIndex(u => u === url)
    const sourceIndex = this.getSourceIndex(url)
    // 删除url和cancel方法
    urlIndex !== -1 && this.requestUrlList?.splice(urlIndex as number, 1)
    sourceIndex !== -1 &&
      this.cancelRequestSourceList?.splice(sourceIndex as number, 1)
  }
  request<T>(config: RequestConfig<T>): Promise<T> {
   
    return new Promise((resolve, reject) => {
   
      startLoading()
      // 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器
      if (config.interceptors?.requestInterceptors) {
   
        config = config.interceptors.requestInterceptors(config)
      }
      const url = config.url
      // url存在保存取消请求方法和当前请求url
      if (url) {
   
        this.requestUrlList?.push(url)
        // TODO 在axios0.22起,对CancelToken已经弃用,需要改成  AbortController 文档:https://axios-http.com/docs/cancellation
        config.cancelToken = new axios.CancelToken(c => {
   
          this.cancelRequestSourceList?.push
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值