关于typescript:使用TS封装axios

一、根本封装

import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig } from 'axios'
class Request {
  // axios 实例
  instance: AxiosInstance
  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
  }
  request(config: AxiosRequestConfig) {
    return this.instance.request(config)
  }
}
export default Request

二、拦截器封装

1.类拦截器:在类中对axios.create()创立的实例调用interceptors下的两个拦截器。

// index.ts
constructor(config: AxiosRequestConfig) {
  this.instance = axios.create(config)

  this.instance.interceptors.request.use(
    (res: AxiosRequestConfig) => {
      console.log('全局申请拦截器')
      return res
    },
    (err: any) => err,
  )
  this.instance.interceptors.response.use(
    // 因为咱们接口的数据都在res.data下,所以咱们间接返回res.data
    (res: AxiosResponse) => {
      console.log('全局响应拦截器')
      return res.data
    },
    (err: any) => err,
  )
}

2.实例拦截器:保障了封装的灵活性,每一个实例中的拦截器后的解决可能不一样。
拦截器的执行程序为实例申请→类申请→实例响应→类响应;这样能够在申请的时候做一些不同的拦挡。

根底拦挡
// types.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface RequestInterceptors {
  // 申请拦挡
  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestInterceptorsCatch?: (err: any) => any
  // 响应拦挡
  responseInterceptors?: (config: AxiosResponse) => AxiosResponse
  responseInterceptorsCatch?: (err: any) => any
}
// 自定义传入的参数
export interface RequestConfig extends AxiosRequestConfig {
  interceptors?: RequestInterceptors
}

定义完根底的拦截器之后,须要革新咱们传入的参数的类型,因为是axios提供的AxiosRequestConfig是不容许咱们传入拦截器的,所以咱们须要自定义拦截器RequestConfig,让其继承AxiosRequestConfig。

// index.ts
import axios, { AxiosResponse } from 'axios'
import type { AxiosInstance, AxiosRequestConfig } from 'axios'
import type { RequestConfig, RequestInterceptors } from './types'

class Request {
  // axios 实例
  instance: AxiosInstance
  // 拦截器对象
  interceptorsObj?: RequestInterceptors

  constructor(config: RequestConfig) {
    this.instance = axios.create(config)
    this.interceptorsObj = config.interceptors

    this.instance.interceptors.request.use(
      (res: AxiosRequestConfig) => {
        console.log('全局申请拦截器')
        return 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) => {
        console.log('全局响应拦截器')
        return res.data
      },
      (err: any) => err,
    )
  }
}

3.接口拦挡:对繁多接口进行拦挡操作
首先将AxiosRequestConfig类型批改为RequestConfig容许传递拦截器;在类拦截器中将接口申请的数据进行了返回,也就是说在request()办法中失去的类型就不是AxiosRequest类型。

查看axios的index.d.ts中对request()办法的类型如下:

    // type.ts
    request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;
也就是说容许咱们传递的类型,从而扭转request()办法的返回值类型:
// index.ts
request<T>(config: RequestConfig): Promise<T> {
  return new Promise((resolve, reject) => {
    // 如果咱们为单个申请设置拦截器,这里应用单个申请的拦截器
    if (config.interceptors?.requestInterceptors) {
      config = config.interceptors.requestInterceptors(config)
    }
    this.instance
      .request<any, T>(config)
      .then(res => {
        // 如果咱们为单个响应设置拦截器,这里应用单个响应的拦截器
        if (config.interceptors?.responseInterceptors) {
          res = config.interceptors.responseInterceptors<T>(res)
        }

        resolve(res)
      })
      .catch((err: any) => {
        reject(err)
      })
  })
}

申请接口拦挡是最前执行,而响应拦挡是最初执行。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理