在vue项目中与后台进行数据交互的时候,我们通常用到的是axios库
安装
通过运行npm install axios
命令进行安装axios库
在此以1.1.3
版本为例
引入和封装
在src目录同级创建service目录,创建request目录,在request目录下创建type.ts
文件来声明类型
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface ZRequestInterceptor<T = AxiosResponse> {
requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorCatch?: (err: any) => any
responseInterceptor?: (config: T) => T
responseInterceptorCatch?: (err: any) => any
}
export interface ZRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
interceptors?: ZRequestInterceptor<T>
}
同时创建index.ts
文件进行封装axios
import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { ZRequestInterceptor, ZRequestConfig } from "@/service/request/type.ts";
export class ZRequest {
instance: AxiosInstance // axios实例
interceptor?: ZRequestInterceptor // 拦截
constructor(config: ZRequestConfig) {
this.instance = axios.create(config)
this.interceptor = config.interceptors
// 在这里可以传入自定义拦截
this.instance.interceptors.request.use(
this.interceptor?.requestInterceptor,
this.interceptor?.requestInterceptorCatch
)
this.instance.interceptors.response.use(
this.interceptor?.responseInterceptor,
this.interceptor?.responseInterceptorCatch
)
// 在此可以设置通用拦截
this.instance.interceptors.request.use(
(config) => {
return config
},
(err) => {
return err
}
)
this.instance.interceptors.response.use(
(res) => {
return res.data
},
(err) => {
if (err.response.state === '404') {
console.log('接口未找到')
}
return err
})
}
request<T>(config: ZRequestConfig<T>): Promise<T> {
return new Promise((resolve, reject) => {
//单个请求的请求拦截
if (config.interceptors?.requestInterceptor) {
config = config.interceptors.requestInterceptor(config)
}
this.instance.request<any, T>(config).then((res) => {
//单个请求的响应拦截
if (config.interceptors?.responseInterceptor) {
res = config.interceptors.responseInterceptor(res)
}
resolve(res)
}).catch((err) => {
reject(err)
})
})
}
post<T>(config: ZRequestConfig<T>): Promise<T> {
return this.request<T>({ ...config, method: 'POST' })
}
}
创建config.ts文件设置基础配置
let BASE_URL: string
const TIMEOUT = 10000
if (process.env.NODE_ENV === 'development') {
BASE_URL = '/boot/'
} else if (process.env.NODE_ENV === 'production') {
BASE_URL = '/prod'
} else {
BASE_URL = '/test'
}
export { BASE_URL, TIMEOUT }
在service目录下创建index.ts文件
import { ZRequest } from './request'
import { BASE_URL, TIMEOUT } from './request/config'
import localCache from '@/utils/cache'
const zRequest = new ZRequest({
baseURL: BASE_URL,
timeout: TIMEOUT,
interceptors: {
requestInterceptor: (config) => {
const token = localCache.getCache('token')
if (token) {
if (config && config.headers) {
config.headers.Authorization = `Bearer ${token}`
}
}
return config
},
requestInterceptorCatch: (err) => {
console.log(err)
return err
},
responseInterceptor: (config) => {
return config
},
responseInterceptorCatch: (err) => {
console.log(err)
return err
}
}
})
export default zqRequest
使用
import request from '@/service/index.ts'
import {IAccount, IDataType, ILoginResultType} from "@/api/type.ts";
enum loginUrl {
login = '/login'
}
export function accountLoginRequest(account: IAccount) {
return request.post<ILoginResultType<IDataType>>({
url: loginUrl.login,
data: account,
// 可进行设置单个接口的拦截
interceptors: {
requestInterceptor: (config) => {
return config
},
responseInterceptor: (res) => {
return res
}
}
})
}
到这里可以进行全部拦截的设置,单个实例的拦截设置,某个请求方式的拦截设置,以及单个接口的拦截设置
如果以上封装有什么错误或不妥的地方,望大佬们多多指点。