安装axios
yarn add axios
区分开发环境
- 方式一:可以自己手动修改,但是不推荐
- 方式二:根据 process.env.NODE_ENV 区分(推荐)
- 方式三:根据 vue-cli 脚手架的 env配置不同开发环境,详情可以看vue-cli官方文档介绍
// src/service/request/config.ts // 根据process.env.NODE_ENV 区分 // 开发环境: development // 生成环境:production // 测试环境: test let BASE_URL = '' const TIME_OUT = 10000 if (process.env.NODE_ENV === 'development') { // 这里BASE_URL 后地址根据实际项目服务器地址填写,这里是示例 BASE_URL = 'http://123.207.32.32:8000' } else if (process.env.NODE_ENV === 'production') { BASE_URL = 'http://elva.org/prod' } else { BASE_URL = 'http://elva.org/test' } export { BASE_URL, TIME_OUT }
实现最基础的封装
// src/service/request/index.ts import axios from 'axios' import type { AxiosInstance, AxiosResponse,AxiosRequestConfig } from 'axios' class XDRequest { // axios 实例 instance: AxiosInstance constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) } request(config: AxiosRequestConfig): void { return this.instance.request(config) } } export default XDRequest
注意:这里封装一个类,是因为类可以new出多个实例
封装拦截器
==注意:==这里的封装思路是
axios 提供的AxiosRequestConfig 类型是不允许我们传入拦截器的,这个时候需要我们自己定义一个接口,使改造后的接口继承AxiosRequestConfig
// src/service/request/type.ts import type { AxiosRequestConfig, AxiosResponse } from 'axios' export interface XDRequestInterceptors { requestIntercetor?: (config: AxiosRequestConfig) => AxiosRequestConfig requestIntercetorCatch?: (error: any) => any responseInterceptor?: (res: AxiosResponse) => AxiosResponse responseInterceptorCatch?: (error: any) => any } export interface XDRequestConfig extends AxiosRequestConfig { interceptors?: XDRequestInterceptors }
1. 类拦截器
只需要在类中在axios.create()创建的实例中调用 interceptors中两个拦截器
image-20220723172447949
完整代码:
// src/service/request/index.ts import axios from 'axios' import type { AxiosInstance, AxiosResponse } from 'axios' import type { XDRequestInterceptors, XDRequestConfig } from './type' class XDRequest { // axios 实例 instance: AxiosInstance constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) // 全局拦截器 this.instance.interceptors.request.use( (config: XDRequestConfig) => { console.log('所有的实例都有的拦截器: 请求成功拦截') return config }, // 请求失败拦截 (err: any) => err ) this.instance.interceptors.response.use( (res: AxiosResponse) => { console.log('所有实例都有的拦截器:响应成功拦截') return res }, // 响应失败拦截 (err: any) => err ) } request(config: AxiosRequestConfig): void { return this.instance.request(config) } } export default XDRequest
2. 实例拦截器
image-20220723172348130
完整代码:
// src/service/request/index.ts import axios from 'axios' import type { AxiosInstance, AxiosResponse } from 'axios' import type { XDRequestInterceptors, XDRequestConfig } from './type' class XDRequest { // axios 实例 instance: AxiosInstance // 拦截器对象 interceptorsObj?: XDRequestInterceptors constructor(config: AxiosRequestConfig) { this.instance = axios.create(config) // 实例拦截器 this.interceptorsObj = config.interceptors this.instance.interceptors.request.use( this.interceptorsObj?.requestIntercetor, this.interceptorsObj?.requestIntercetorCatch ) this.instance.interceptors.response.use( this.interceptorsObj?.responseInterceptor, this.interceptorsObj?.responseInterceptorCatch ) // 全局拦截器(所有实例都有的拦截器) this.instance.interceptors.request.use( (config: XDRequestConfig) => { console.log('所有的实例都有的拦截器: 请求成功拦截') return config }, // 请求失败拦截 (err: any) => err ) this.instance.interceptors.response.use( (res: AxiosResponse) => { console.log('所有实例都有的拦截器:响应成功拦截') return res }, // 响应失败拦截 (err: any) => err ) } request(config: AxiosRequestConfig): void { return this.instance.request(config) } } export default XDRequest
3. 接口(单一方法)拦截器
image-20220723172629476
完整代码:
import axios from 'axios' import type { AxiosInstance, AxiosResponse } from 'axios' import type { XDRequestInterceptors, XDRequestConfig } from './type' class XDRequest { // axios 实例 instance: AxiosInstance // 拦截器对象 interceptorsObj?: XDRequestInterceptors // 使用拦截器 constructor(config: XDRequestConfig) { this.instance = axios.create(config) // 1. 使用实例拦截器 this.interceptorsObj = config.interceptors this.instance.interceptors.request.use( this.interceptorsObj?.requestIntercetor, this.interceptorsObj?.requestIntercetorCatch ) this.instance.interceptors.response.use( this.interceptorsObj?.responseInterceptor, this.interceptorsObj?.responseInterceptorCatch ) // 2. 全局拦截器(所有实例都有的拦截器) this.instance.interceptors.request.use( (config: XDRequestConfig) => { console.log('所有的实例都有的拦截器: 请求成功拦截') return config }, // 请求失败拦截 (err: any) => err ) this.instance.interceptors.response.use( (res: AxiosResponse) => { console.log('所有实例都有的拦截器:响应成功拦截') return res }, // 响应失败拦截 (err: any) => err ) } // 3. 为单个请求添加拦截器 request(config: XDRequestConfig): void { // 如果我们为单个请求添加拦截器,这里使用单个请求的拦截 if (config.interceptors?.requestIntercetor) { config = config.interceptors.requestIntercetor(config) } this.instance.request(config).then((res) => { // 如果我们为单个响应添加拦截器,这里使用单个响应的拦截 if (config.interceptors?.responseInterceptor) { res = config.interceptors.responseInterceptor(res) } console.log(res) }) } } export default XDRequest
测试:
// src/service/index.ts // 测试实例拦截器 import XDRequest from './request' import { BASE_URL, TIME_OUT } from './request/config' const xdRequest = new XDRequest({ baseURL: BASE_URL, timeout: TIME_OUT, interceptors: { requestIntercetor: (config) => { console.log('请求成功拦截') return config }, requestIntercetorCatch: (err) => { console.log('请求拦截失败') return err }, responseInterceptor: (res) => { console.log('响应成功拦截') return res }, responseInterceptorCatch: (err) => { console.log('响应失败的拦截') return err } } }) export default xdRequest
// 在整个mian.ts添加代码测试全局拦截器 import xdRequest from './service' xdRequest.request({ url: '/home/multidata', method: 'GET', interceptors: { requestIntercetor: (config) => { console.log('单独请求的config') return config } } })
结果: