<article class=“article fmt article-content”><h2>一、根本封装</h2><pre><code>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</code></pre><h2>二、拦截器封装</h2><p>1.类拦截器:在类中对axios.create()创立的实例调用interceptors下的两个拦截器。</p><pre><code>// index.tsconstructor(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, )}</code></pre><p>2.实例拦截器:保障了封装的灵活性,每一个实例中的拦截器后的解决可能不一样。<br/>拦截器的执行程序为实例申请→类申请→实例响应→类响应;这样能够在申请的时候做一些不同的拦挡。</p><pre><code>根底拦挡// types.tsimport 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}</code></pre><p>定义完根底的拦截器之后,须要革新咱们传入的参数的类型,因为是axios提供的AxiosRequestConfig是不容许咱们传入拦截器的,所以咱们须要自定义拦截器RequestConfig,让其继承AxiosRequestConfig。</p><pre><code>// index.tsimport 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, ) }}</code></pre><p>3.接口拦挡:对繁多接口进行拦挡操作<br/>首先将AxiosRequestConfig类型批改为RequestConfig容许传递拦截器;在类拦截器中将接口申请的数据进行了返回,也就是说在request()办法中失去的类型就不是AxiosRequest类型。</p><p>查看axios的index.d.ts中对<strong>request()</strong>办法的类型如下:</p><pre><code> // type.ts request<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;也就是说容许咱们传递的类型,从而扭转request()办法的返回值类型:// index.tsrequest<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) }) })}</code></pre><p>申请接口拦挡是最前执行,而响应拦挡是最初执行。</p></article>