一. 前言
在开发 uni-app 项目时,我们经常需要对接后端接口进行数据请求。虽然 uni-app 框架本身提供了uni.request
用于发起请求,但在实际项目中,我们往往会封装一些请求库来简化请求的操作,提高代码复用性和可维护性。
本文将介绍基于 uni.request
实现一款小而美的请求工具,通过大约 100 行代码的实现,为 uni-app 项目打造一个简洁高效的请求库。
二. 请求库的设计思路
1. 了解 uni.request
在 uni-app 中使用 uni.request
来发起请求,但这种直接调用 uni.request
的方式在实际开发中存在一些不足之处,比如请求逻辑过于分散、请求参数拼接繁琐等。因此,我们希望通过封装一个简单的请求库来优化这一过程。
在 uni-app 使用 uni.request
的方式:
1 | js复制代码uni.request({ |
以上的这种请求方式是在 uni-app 项目中最常见的代码书写方式,很简单也很好理解,但是无法支持 promise API 式的请求,不支持请求和响应拦截器,同时也不支持全局的变量配置,逻辑分散,不便于维护!
不过我最近看官方文档,官方已经对部分 API 进行了 Promise 封装
详情参考:官方 Promise - 封装
2. 请求库的实现目标
我的目标核心是实现一个基于 Promise 的,轻量且强大的 http 网络库,基于以上这个目标,我的请求库应该具备以下基本功能:
- 提供统一的
Promise API
- 基于
uni.request
,支持多种运行环境,浏览器 H5、小程序、APP 等 - 支持发起
GET
、POST
、PUT
、DELETE
请求 - 支持请求/响应拦截器
- 支持设置请求的
header
- 支持处理请求的
loading
状态 - 支持对请求结果进行统一处理
- 支持链式调用
三. 请求库实现
基于以上的目标特性,我会一步一步实现请求库,而它的实现应该主要包括以下几个核心点:
- Config 配置项:设计一个统一的配置项对象
config
,其中包含了 baseURL、header、data、method、dataType、responseType 等网络请求的基本配置信息。这样可以确保在发起网络请求时,可以统一管理这些配置项,方便进行全局设置和覆盖。 - 拦截器 Interceptors:设计请求拦截器和响应拦截器,提供
use
方法来添加拦截器处理函数。请求拦截器可以在发送请求前对请求参数进行处理,而响应拦截器则可以在收到响应后对响应结果进行处理。通过拦截器可以实现一些通用的网络请求处理逻辑,比如添加请求头、处理请求参数、统一处理响应结果等。 - 链式调用:在
setBaseURL
、setHeader
、setData
等方法中都使用了链式调用的方式,即每一个方法返回当前实例的引用,使得可以连续调用多个方法来设置请求的各个参数,提高代码的可读性和可维护性。 - Promise 处理:在
request
方法中使用了 Promise 对网络请求的结果进行处理,包括请求成功和失败的处理逻辑。同时也通过 Promise 来处理拦截器的返回结果,保证请求和拦截器的执行顺序和逻辑。 - 错误处理:在请求完成后,根据返回的状态码来判断请求的成功与失败,并通过不同的处理逻辑来处理不同状态下的响应结果。同时,在拦截器和请求的过程中,也会对错误进行处理,保证请求过程的稳定性和可靠性。
接下来我们分别对以上的核心点进行一一实现:
1. 构造函数
- 在构造函数中,初始化
config
对象和interceptors
对象,分别用来存储请求的配置信息和拦截器。 config
包含了 baseURL、header、data、method、dataType、responseType、success、fail 和 complete 等属性。interceptors
包含了 request 和 response 拦截器,用来处理请求和响应的拦截操作。
通过构造函数,来定义统一的公共变量
1 | js复制代码class Http { |
2. 设置 BaseURL
定义 setBaseURL
方法,用来设置请求的基础 URL 统一请求前缀,将传入的 baseURL 参数赋值给 config.baseURL 属性。
1 | js复制代码function setBaseURL(baseURL) { |
3. 设置请求 header
定义 setHeader
方法,用来设置请求的头部信息,将传入的 header 参数与原有的 header 属性合并更新。
1 | js复制代码function setHeader(header) { |
4. 设置请求体
定义 setData
方法,用来设置请求的数据,根据传入的数据类型判断是直接赋值还是合并更新到 config.data 属性中。
1 | js复制代码function setData(data) { |
5. 设置拦截器
设计请求拦截器和响应拦截器,提供 use
方法来添加拦截器处理函数。请求拦截器可以在发送请求前对请求参数进行处理,而响应拦截器则可以在收到响应后对响应结果进行处理。
通过拦截器可以实现一些通用的网络请求处理逻辑,比如添加请求头、处理请求参数、统一处理响应结果等。
1 | js复制代码this.interceptors = { |
6. 基于 Promise 对象来实现
通过以上的配置,其实我们已经完成了一半,接下来,使用这些配置好的变量按需使用 uni.request
就可以了,是不是很简单?
而 request 方法应该包含以下内容:
request
方法用来发起请求,根据传入的 URL、数据和选项进行请求配置。- 先处理请求的基础配置,包括 URL、baseURL、header、method、dataType 等。
- 接着处理拦截器,分为 request 和 response 拦截器,根据拦截器的设置进行相应的拦截操作。
- 最后返回一个 Promise 对象,实现异步请求的链式调用,并根据请求结果执行相应的回调处理。
接下来,我们按部就班的来实现我们最重要的 request 方法
1 | js复制代码function request(url, data, options) { |
综上所述,以上请求库的设计思路是以封装、拓展性和易用性为核心,通过配置项、拦截器、链式调用和 Promise 处理等设计,实现了一个简单但功能完善的网络请求库,适用于处理各种类型的网络请求需求。
总的来说,以上代码实现了一个简洁易用的 HTTP 请求类,结合了配置管理、拦截器功能和异步请求处理,并提供了一些常用的方法来方便进行 HTTP 请求的管理和处理。
四. 使用方式
1. npm 安装
我已经将uni-http
的请求库发到了npm
上了,并且在多个项目中得到了良好的应用,可直接使用 npm
安装使用,通过如下方式进行安装:
1 | bash复制代码// 安装 |
点击查看在 npm 上完整的 uni-http 请求库,欢迎大家使用:npm 地址
2. 快速上手
实例化 Http 类
Http 为一个类,所以在使用前需要实例化 new
,通过构造函数实例化一些必备参数
1 | js复制代码import { Http } from "@anyup/uni-http"; |
设置拦截器
- 通过
interceptors.request.use
设置请求拦截器,主要对请求 header 的配置,比如 token 等。 - 通过
interceptors.response.use
设置响应拦截器,如果需要,可以对所有的请求成功的响应数据做统一的业务处理,以简化代码。
1 | js复制代码// 设置请求拦截器 |
请求示例
以登录请求为示例,通过传递 url,data,option,分别配置请求的 api 地址,请求参数,以及请求的个性化配置(是否需要请求 loading 等)。
1 | js复制代码// 登录请求示例,并配置请求时显示loading |
五. 总结
通过以上代码的实现,我们成功构建了一个简洁高效的 uni-app 请求库,实现了一个小而美的 uni-app 请求库,能够满足常见的请求需求,同时除去注释,代码量也被控制在了 100 行左右。而且还实现了统一请求响应拦截器、全局错误处理等功能,使用它可以让我们的项目开发变得更加顺畅和便利。
希望本文能够对大家在 uni-app 项目中封装请求库有所帮助,让我们的开发工作更加高效和便捷。
在实际项目中,如果你有任何疑问或建议,欢迎联系我,我可以根据需求继续扩展这个请求库。
六. 结语
- 如果你有任何问题,或者想要共同学习交流,欢迎通过沸点联系我:点击查看沸点
- 剧透:篇幅有限,下篇文章我会继续以此为基础,说明如何实现批量生成 API 请求,简化代码量 99.99%,通过类的工厂模式,搞定繁琐的请求 function 定义,敬请关注!
源码
开源不易,欢迎 Start、Fork
本文正在参加金石计划征文活动,欢迎点赞、收藏加关注,欢迎在评论区留言,让我们一起讨论进步!
本文转载自: 掘金