TS 和 JS 封装 Axios 的实现

410 阅读3分钟

TS + ElementPlus 实现请求加载动画

type.ts

import type { AxiosRequestConfig} from "axios"
// 自定义拦截器类型
export interface XyRequestInterceptors {
  requestInterceptor?: (config: AxiosRequestConfig) => any // 请求成功拦截
  requestInterceptorCatch?: (error: any) => any // 请求失败拦截
  responseInterceptor?: (response: any) => any // 响应成功拦截
  responseInterceptorCatch?: (error: any) => any // 响应失败拦截
}
// 扩展默认类型
export interface XyRequestConfig extends AxiosRequestConfig {
  interceptors?: XyRequestInterceptors
  showLoading?: boolean
}
export const DEAFULT_LADING = true // 默认是否开启加载动画

request.ts

import axios from "axios"
import type { AxiosInstance } from "axios"
import { DEAFULT_LADING, type XyRequestConfig, type XyRequestInterceptors } from "./type"

class XyRequest {
  instance: AxiosInstance // axios实例
  interceptors?: XyRequestInterceptors // 单例拦截器
  loading?: any // 加载动画实例
  isLoading: boolean = DEAFULT_LADING // 加载状态 防止重复进行加载动画
  showLoading: boolean = DEAFULT_LADING // 否开启加载动画
  constructor(config: XyRequestConfig) {
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.alone()
    this.all()
  }
  // 单例拦截
  alone() {
    // 注册单例请求拦截
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestInterceptorCatch
    )
    // 注册单例响应拦截
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor,
      this.interceptors?.responseInterceptorCatch
    )
  }
  // 全局拦截
  all() {
    // 注册全局请求拦截
    this.instance.interceptors.request.use(
      (config: any) => {
        // 不存在加载中的时候在调用加载动画
        if (this.showLoading && this.isLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: "Loading",
            background: "rgba(0, 0, 0, 0.7)"
          })
          this.isLoading = false
        }
        return config
      },
      (err) => {
        return err
      }
    )
    // 注册全局响应拦截
    this.instance.interceptors.response.use(
      (res: any) => {
        this.loading?.close()
        this.isLoading = DEAFULT_LADING
        return res
      },
      (err) => {
        setTimeout(() => {
        this.loading?.close()
        this.isLoading = DEAFULT_LADING
        }, 1000)
        return err
      }
    )
  }

  // 网络请求
  request<T = any>(config: XyRequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      // 单独请求拦截
      config = config.interceptors?.requestInterceptor
        ? config.interceptors.requestInterceptor(config)
        : config
      // 是否关闭加载动画
      this.showLoading = config.showLoading == false ? false : true
      this.instance
        .request<T, any>(config)
        .then((res) => {
          // 单独响应拦截
          res = config.interceptors?.responseInterceptor
            ? config.interceptors.responseInterceptor(res)
            : res
          this.showLoading = DEAFULT_LADING // 还原状态
          resolve(res)
        })
        .catch((err) => {
          this.showLoading = DEAFULT_LADING // 还原状态
          reject(err)
        })
    })
  }

  get<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "GET" })
  }

  post<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "POST" })
  }

  delete<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "DELETE" })
  }

  patch<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "PATCH" })
  }
}

export default XyRequest

TS纯净版

type.ts 同上

request.ts

import axios from "axios"
import type { AxiosInstance } from "axios"
import type { XyRequestConfig, XyRequestInterceptors } from "./type"

class XyRequest {
  instance: AxiosInstance // axios实例
  interceptors?: XyRequestInterceptors // 单例拦截器
  constructor(config: XyRequestConfig) {
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.alone()
    this.all()
  }
  // 单例拦截
  alone() {
    // 注册单例请求拦截
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestInterceptorCatch
    )
    // 注册单例响应拦截
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor,
      this.interceptors?.responseInterceptorCatch
    )
  }
  // 全局拦截
  all() {
    // 注册全局请求拦截
    this.instance.interceptors.request.use(
      (config: any) => {
        return config
      },
      (err) => {
        return err
      }
    )
    // 注册全局响应拦截
    this.instance.interceptors.response.use(
      (res: any) => {
        return res
      },
      (err) => {
        return err
      }
    )
  }

  // 网络请求
  request<T = any>(config: XyRequestConfig): Promise<T> {
    return new Promise((resolve, reject) => {
      // 单独请求拦截
      config = config.interceptors?.requestInterceptor
        ? config.interceptors.requestInterceptor(config)
        : config
      this.instance
        .request<T, any>(config)
        .then((res) => {
          // 单独响应拦截
          res = config.interceptors?.responseInterceptor
            ? config.interceptors.responseInterceptor(res)
            : res
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "GET" })
  }

  post<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "POST" })
  }

  delete<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "DELETE" })
  }

  patch<T = any>(config: XyRequestConfig): Promise<T> {
    return this.request({ ...config, method: "PATCH" })
  }
}

export default XyRequest

JS纯净版

request.ts

import axios from "axios"

class XyRequest {
  instance // axios实例
  interceptors // 单例拦截器
  constructor(config) {
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.alone()
    this.all()
  }
  // 单例拦截
  alone() {
    // 注册单例请求拦截
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestInterceptorCatch
    )
    // 注册单例响应拦截
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor,
      this.interceptors?.responseInterceptorCatch
    )
  }
  // 全局拦截
  all() {
    // 注册全局请求拦截
    this.instance.interceptors.request.use(
      (config) => {
        return config
      },
      (err) => {
        return err
      }
    )
    // 注册全局响应拦截
    this.instance.interceptors.response.use(
      (res) => {
        return res
      },
      (err) => {
        return err
      }
    )
  }

  // 网络请求
  request(config) {
    return new Promise((resolve, reject) => {
      // 单独请求拦截
      config = config.interceptors?.requestInterceptor
        ? config.interceptors.requestInterceptor(config)
        : config
      this.instance
        .request(config)
        .then((res) => {
          // 单独响应拦截
          res = config.interceptors?.responseInterceptor
            ? config.interceptors.responseInterceptor(res)
            : res
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get(config) {
    return this.request({ ...config, method: "GET" })
  }

  post(config) {
    return this.request({ ...config, method: "POST" })
  }

  delete(config) {
    return this.request({ ...config, method: "DELETE" })
  }

  patch(config) {
    return this.request({ ...config, method: "PATCH" })
  }
}

export default XyRequest

小程序适配

安装 axios-miniprogram-adapter

添加到 request.ts

import mpAdapter from "axios-miniprogram-adapter";
axios.defaults.adapter = mpAdapter;

使用

index.ts

import XyRequest from "./request/request"
const request = new XyRequest({
  baseURL: "http://127.0.0.1:3000",
  timeout: 10000,
  headers: {
    "Content-type": "application/json;charset=UTF-8",
    "Access-Control-Allow-Origin": "*"
  },
  interceptors: {
    requestInterceptor: (config: any) => {
      // token
      // const token = window.localStorage.getItem("token")
      // if (token) {
      //   config.headers.Authorization = `Bearer ${token}`
      // }
      return config
    },
    requestInterceptorCatch: (err) => {
      return err
    },
    responseInterceptor: (res) => {
      return res.data
    },
    responseInterceptorCatch: (err) => {
      return err
    }
  }
})

export default request

api.ts

import request from "../index"

// post方式
export function login(data: any) {
  return request.post<any>({
    url: "/login",
    data
  })
}
// get方式
export function unify(params: any) {
  return request.get<any>({
    url: "/unify",
    params
  })
}