前言
最近学习了vue3又学习了ts,学完准备搭建一个项目练练手时。突然想起现在封装的网络请求貌似是vue2和原生js以及axios结合使用的,所以当我们使用vue3和ts进行开发的时候那肯定也得根据当前的技术来重新封装一个结构性更强的基于axios的网络请求体系。封装好了我们以后搭建项目可以说直接采用就好了,学习此文能让我们体会ts在封装网络请求时所给予更加完善的安全性,让我们来看看ts的独特魅力吧。
结构预览及说明
- src下新建service文件夹为主文件夹
- request为封装请求的文件夹
- config.ts 为一些请求的固定配置及不同的开发环境中的值
- errCode.ts 为错误请求码的对应状态信息
- index.ts 为主要构造请求类的关键配置
- type.ts 为导出需要用到的一些自定义接口的类型
- service.ts中的index.ts 则是实例化构造类生成真正的网络请求配置并返回
现在我们结构已经了解清楚了,让我开始搭建吧!
构造类 ZJRequest
我们主要的工作都是在构造类ZJRequest中进行配置,配置好后,只需要实例化ZJRequest类并传入对应配置即可得到一个完整的网络请求配置对象。这里的命名推荐大家使用自己独有的昵称加Request来进行命名,这也是一种开发习惯。我这边搭建的网络请求配置包含了拦截器完整配置及响应遮罩完整配置。先看一看最标准的基本配置吧。
import type { AxiosInstance,AxiosRequestConfig } from 'axios'
import axios from 'axios'
class ZJRequest {instance: AxiosInstanceconstructor(config: AxiosRequestConfig) {this.instance = axios.create(config) //根据传入配置手动创建实例 }
先简单说下上面的类型问题吧,构造ZJRequest类其中的instance或是传入的参数config现在我们使用ts肯定是需要对其进行类型规范的,而他们的类型其实在axios是有给出的,我们只需要引用即可。
很简洁的一段代码只需要根据传入的配置调用axios创建新的Instance实例就可以得到基本的网络配置了,显然我们并不需要这么简单的封装,这样我们的封装变得意义不大,所以我们也知道拦截器和响应遮罩才是重点封装对象,下面让我们来看看这是如何实现的吧。
拦截器实现解读
先贴一份完整的请求代码吧,方便我们进行讲解它的实现过程。
import type { AxiosInstance } from 'axios'
import type { KZJRequestInterceptors, KZJRequestConfig } from './type'
import { getErrMessage } from './errCode'
import axios from 'axios'
import { ElLoading } from 'element-plus'
import type { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type'
const DEFAULT_LOADING = true
class ZJRequest {instance: AxiosInstanceinterceptors?: KZJRequestInterceptorsshowLoading: booleanloading?: ILoadingInstanceconstructor(config: KZJRequestConfig) {//KZJRequestConfig继承自AxiosRequestConfig并进行了拦截器接口扩展this.instance = axios.create(config) //根据传入配置手动创建实例this.interceptors = config.interceptors //添加拦截器this.showLoading = config.showLoading ?? DEFAULT_LOADING //控制loading显示// 使用拦截器// 1.从config中取出的拦截器是对应的实例的拦截器this.instance.interceptors.request.use(this.interceptors?.requestInterceptor, //请求成功拦截this.interceptors?.requestInterceptorCatch //请求失败拦截)this.instance.interceptors.response.use(this.interceptors?.responseInterceptor, //响应成功拦截this.interceptors?.responseInterceptorCatch //响应失败拦