可以直接拿走使用的TypeScript二次封装的axios库
为什么要封装axios
- 降低耦合度,方便后期维护
- 如果不进行封装,就会造成耦合度太高,一旦
axios
库不再维护,需要换库就很麻烦,需要一个页面一个页面的去找到并更改,这就会造成不必要的麻烦 - 而封装之后,只需要修改一个地方即可
实现功能
- 实现三类拦截器:不同实例的所有请求、同一个实例的所有请求、同一个实例的部分请求
- 根据需求可创建多个实例对象
- 拦截
token
- 可选是否有
loading
动画
loading
动画使用了element-plus
组件库
具体代码如下
import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { LXRequestInterceptors, LXRequestConfig } from './type'
import { ElLoading, ILoadingInstance } from 'element-plus'
const DEFAULT_LOADING = true
class LXRequest {
instance: AxiosInstance
interceptors?: LXRequestInterceptors
showLoading: boolean
loading?: ILoadingInstance
constructor(config: LXRequestConfig) {
this.instance = axios.create(config)
this.showLoading = config.showLoading ?? DEFAULT_LOADING
this.interceptors = config.interceptors
this.instance.interceptors.request.use(
this.interceptors?.requestInterceptor,
this.interceptors?.requestInterceptorCatch
)
this.instance.interceptors.response.use(
this.interceptors?.responseInterceptor,
this.interceptors?.responseInterceptorCatch
)
this.instance.interceptors.request.use(
(config) => {
if (this.showLoading) {
this.loading = ElLoading.service({
lock: true,
text: '正在请求数据...',
background: 'rgba(0, 0, 0, 0.5)'
})
}
return config
},
(err) => {
return err
}
)
this.instance.interceptors.response.use(
(res) => {
this.loading?.close()
const data = res.data
if (data.returnCode === '-1001') {
} else {
return data
}
},
(err) => {
this.loading?.close()
if (err.response.status === 404) {
console.log('404错误~')
}
return err
}
)
}
request<T = any>(config: LXRequestConfig<T>): Promise<T> {
return new Promise((resolve, reject) => {
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config)
}
if (config.showLoading === false) {
this.showLoading = config.showLoading
}
this.instance
.request<any, T>(config)
.then((res) => {
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res)
}
this.showLoading = DEFAULT_LOADING
resolve(res)
})
.catch((err) => {
this.showLoading = DEFAULT_LOADING
reject(err)
return err
})
})
}
get<T = any>(config: LXRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'GET' })
}
post<T = any>(config: LXRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'POST' })
}
delete<T = any>(config: LXRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'DELETE' })
}
patch<T = any>(config: LXRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'PATCH' })
}
}
export default LXRequest
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface LXRequestInterceptors<T = AxiosResponse> {
requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorCatch?: (error: any) => any
responseInterceptor?: (res: T) => T
responseInterceptorCatch?: (error: any) => any
}
export interface LXRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: LXRequestInterceptors<T>
showLoading?: boolean
}
service/request/config.ts
let BASE_URL = ''
const TIME_OUT = 10000
if (process.env.NODE_ENV === 'development') {
BASE_URL = 'http://lx.org/development'
} else if (process.env.NODE_ENV === 'production') {
BASE_URL = 'http://lx.org/production'
} else {
BASE_URL = 'http://lx.org/test'
}
export { BASE_URL, TIME_OUT }
import LXRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'
import localCache from '@/utils/cache'
const lxRequest = new LXRequest({
baseURL: BASE_URL,
timeout: TIME_OUT,
interceptors: {
requestInterceptor: (config) => {
const token = localCache.getCache('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
requestInterceptorCatch: (err) => {
return err
},
responseInterceptor: (res) => {
return res
},
responseInterceptorCatch: (err) => {
return err
}
}
})
export default lxRequest
class LocalCache {
setCache(key: string, value: any) {
window.localStorage.setItem(key, JSON.stringify(value))
}
getCache(key: string) {
const value = window.localStorage.getItem(key)
if (value) {
return JSON.parse(value)
}
}
deleteCache(key: string) {
window.localStorage.removeItem(key)
}
clearCache() {
window.localStorage.clear()
}
}
export default new LocalCache()