想必作为为一名前端工程师,在开发项目的过程中,没少和 Axios 打交道吧。今天我们对 Axios 进行一次封装,让代码更具健壮性。
在 services 文件夹下创建 index.ts 文件。紧接着创建 config 文件夹,定义常量 BASE_URL 和 TIME_OUT。接着在 request 文件夹下对 axios 方法进行封装。
1 2 3 4 5 6 7 8 9 10
| import { BASE_URL, TIME_OUT } from './config' import LYRequest from './request'
const lyRequest = new LYRequest({ baseURL: BASE_URL, timeout: TIME_OUT, })
export default lyRequest
|
在开发项目中,往往开发环境和生产环境所用到的服务器不同,我们要根据所处的环境给 BASE_URL 赋不同的服务器地址。
1 2 3 4 5 6 7 8 9 10
|
export let BASE_URL = '' if (import.meta.env.DEV) { BASE_URL = 'http://codercba.com:1888' } else { BASE_URL = 'http://codercba.com:8000/' }
export const TIME_OUT = 10000
|
我的项目采用的是 Vite 这个构建工具,它给我们提供了 import
这个方法,在这个方法下有 meta 属性中包含 env 这个环境变量对象,在这里可以这指定 Vite 根据不同的环境做不同的处理。
紧接着对 Axios 进行封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| import axios, { type AxiosInstance, type InternalAxiosRequestConfig } from 'axios' import type { LYRequestConfig } from './type'
class LYRequest { instance: AxiosInstance
constructor(config: LYRequestConfig) { this.instance = axios.create(config)
this.instance.interceptors.request.use( (config) => { console.log('全局请求成功拦截')
return config }, (err) => { console.log('全局请求失败拦截')
return err } ) this.instance.interceptors.response.use( (res) => { console.log('全局响应成功拦截')
return res.data }, (err) => { console.log('全局响应失败拦截') return err } )
this.instance.interceptors.request.use( config.interceptors?.requestSuccessFn, config.interceptors?.requestFailureFn ) this.instance.interceptors.response.use( config.interceptors?.responseSuccessFn, config.interceptors?.responseFailureFn ) }
request<T = any>(config: LYRequestConfig<T>) { if (config.interceptors?.requestSuccessFn) { config = config.interceptors.requestSuccessFn(config as InternalAxiosRequestConfig) }
return new Promise<T>((resolve, reject) => { this.instance .request<any, T>(config) .then((res) => { if (config.interceptors?.responseSuccessFn) { res = config.interceptors.responseSuccessFn(res) } resolve(res) }) .catch((err) => { reject(err) }) }) }
get<T = any>(config: LYRequestConfig<T>) { return this.request({ ...config, method: 'GET' }) }
post<T = any>(config: LYRequestConfig<T>) { return this.request({ ...config, method: 'POST' }) } }
export default LYRequest
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| import type { AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
export interface LYInterceptors<T = AxiosResponse> { requestSuccessFn?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig requestFailureFn?: (err: any) => any responseSuccessFn?: (config: T) => T responseFailureFn?: (err: any) => any }
export interface LYRequestConfig<T = any> extends AxiosRequestConfig { interceptors?: LYInterceptors<T> }
|
至此对 axios 的封装就告一段落。上面代码我是跟着Coderwhy 一步步写的。让我写我也只能对 Axios 做简单的封装。毕竟 TypeScript 太难了。在对 Axios 封装过程中还大量用到泛型,泛型是 TypeScript 中最难的知识点之一。