关于typescript:使用TS封装axios

5次阅读

共计 2999 个字符,预计需要花费 8 分钟才能阅读完成。

一、根本封装

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)
      })
  })
}

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

正文完
 0