1、为什么要对axios进行封装,而不在项目中需要的模块直接使用axios进行网络请求?
- ①方便更换axios;万一axios突然不更新了,我们可以快速切换到其他网络库
- ②方便对网络公共逻辑进行抽取 (比如loading、token等等)
2、具体封装代码如下:
import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElLoading } from 'element-plus'
import { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type'
interface HYRequestInterceptors<T = AxiosResponse> {
requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorCatch?: (error: any) => any
responseInterceptor?: (res: T) => T
responseInterceptorCatch?: (error: any) => any
}
interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: HYRequestInterceptors<T>
showLoading?: boolean
}
const DEAFULT_LOADING = true
class HYRequest {
instance: AxiosInstance
interceptors?: HYRequestInterceptors
showLoading: boolean
loading?: ILoadingInstance
constructor(config: HYRequestConfig) {
// 创建axios实例
this.instance = axios.create(config)
// 保存基本信息
this.showLoading = config.showLoading ?? DEAFULT_LOADING
this.interceptors = config.interceptors
// 使用拦截器
// 1.从config中取出的拦截器是对应的实例的拦截器
this.instance.interceptors.request.use(
this.interceptors?.requestInterceptor,
this.interceptors?.requestInterceptorCatch
)
this.instance.interceptors.response.use(
this.interceptors?.responseInterceptor,
this.interceptors?.responseInterceptorCatch
)
// 2.添加所有实例都有的拦截器
this.instance.interceptors.request.use(
(config) => {
console.log('所有实例都有的拦截器:请求成功拦截')
if (this.showLoading) {
this.loading = ElLoading.service({
lock: true,
text: '正在请求数据',
background: 'rgba(0, 0, 0, 0.5)'
})
}
return config
},
(err) => {
console.log('所有实例都有的拦截器:请求失败拦截')
return err
}
)
this.instance.interceptors.response.use(
(res) => {
console.log('所有实例都有的拦截器:相应成功拦截')
// 将loading移除
setTimeout(() => {
this.loading?.close()
}, 3000)
const data = res.data
if (data.returnCode === '-1001') {
console.log('请求失败!错误信息')
} else {
return data
}
},
(err) => {
console.log('所有实例都有的拦截器:响应失败拦截')
// 将loading移除
this.loading?.close()
// 例子:判断不同的HttpErrorCode显示不同的错误信息
if (err.response.status === 404) {
console.log('404错误信息~')
}
return err
}
)
}
request<T>(config: HYRequestConfig<T>): Promise<T> {
return new Promise((resolve, reject) => {
// 1.单个请求针对请求config的处理
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config)
}
// 2.判断是否需要显示loading
if (config.showLoading == false) {
this.showLoading = config.showLoading
}
this.instance
.request<any, T>(config)
.then((res) => {
// 1.单个请求对数据的处理
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res)
}
// 2.将showLoading设置为默认值,这样不会影响下一次请求
this.showLoading = DEAFULT_LOADING
// 3.将结果resolve返回出去
resolve(res)
})
.catch((err) => {
// 将showLoading设置为默认值,这样不会影响下一次请求
this.showLoading = DEAFULT_LOADING
reject(err)
return err
})
})
}
get<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'GET' })
}
post<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'POST' })
}
delete<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'DELETE' })
}
patch<T>(config: HYRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'PATCH' })
}
}
export default HYRequest
// service 统一出口
import HYRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'
const hyRequest = new HYRequest({
baseURL: BASE_URL,
timeout: TIME_OUT,
interceptors: {
requestInterceptor: (config) => {
// 携带token的拦截
const token = ''
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
console.log('请求成功的拦截')
return config
},
requestInterceptorCatch: (err) => {
console.log('请求失败的拦截')
return err
},
responseInterceptor: (res) => {
console.log('响应成功的拦截')
return res
},
responseInterceptorCatch: (err) => {
console.log('响应失败的拦截')
return err
}
}
})
export default hyRequest
interface DataType {
data: any
returnCode: string
success: boolean
}
hyRequest
.get<DataType>({
url: '/home/multidata',
showLoading: true
})
.then((res) => {
console.log(res.data)
console.log(res.returnCode)
console.log(res.success)
})
网友评论