100 行代码打造小而美的 uni-app 请求库(二)

1,828 阅读5分钟

image.png

100 行代码打造小而美的 uni-app 请求库(一)

100 行代码打造小而美的 uni-app 请求库(二)

打造高效的 uni-app 网络请求流程:自定义 Request 请求库最佳实践

一. 前言

之前通过一篇文章的介绍,详细说明了在 uni-app 框架中,使用大约100 行代码 打造小而美的 uni-app 请求库,基于  uni.request,支持多种运行环境,包括浏览器 H5、小程序、APP 等各端。

文章链接:100 行代码打造小而美的 uni-app 请求库(一)

因为我已经用 uni-http 开发了许多个成型的 APP、H5、 及小程序,Android 和 iOS 均已正常上线应用商店,因此可以证明,它的兼容性是良好的。

本篇文章我们继续聊聊 uni-http 这个请求框架,并主要实现以下功能:

  • 支持处理请求的 loading 状态

  • 支持 upload 文件上传

二. uni-http 是什么

uni-http 基于 uni.request 封装的一款小而美的请求工具库,它具有开箱即用,简洁高效的应用特点。uni-http 使用 TypeScript 开发, 支持 Vue2、Vue3 版本的 uni-app,支持 H5,APP,微信小程序等。

假设我们的文中使用的 http 是已经经过实例化后的实例:

const http = new Http();

// 设置统一的头部
const header = { "Content-Type": "application/json" };

// 仅为示例 API 域名,使用时替换自己的接口域名即可
const baseURL = "https://www.example.com";

// 设置 baseURL 和 header,支持链式调用
http.setBaseURL(baseURL).setHeader(header);

uni-http 最终实现的主要功能有以下几个重要点:

1. 提供统一的 Promise API

http
  .request(url, params)
  .then((res) => {
    // 请求成功处理
  })
  .catch((err) => {
    // 请求错误处理
  });

2. 支持发起 GETPOSTPUTDELETE 请求

http.get(url, params, config);
http.post(url, params, config);
http.put(url, params, config);
http.delete(url, params, config);

3. 支持请求/响应拦截器

// 请求拦截器
http.interceptors.request.use(request, error);
// 响应拦截器
http.interceptors.response.use(request, error);

4. 支持链式调用

http.setBaseURL(baseURL).setHeader(header);

三. 支持处理请求的 loading 状态

前篇文章在说明请求 loading 状态的时候,并没有详细的说明,如何在请求的时候使用 loading

在使用 uni-http 请求的时候是可以声明是否配置 loading 参数的,比如:

// 用户登录接口
http.post("/api/login", { username, password }, { loading: true }).then((res) => {
  // 处理 response 响应
  if (res.status === 1) {
    console.log(res);
  }
});

以上的代码表示,用户在登录的时候,配置显示 loading,那么我们可以在请求拦截器,响应拦截器中判断是否有配置 loading,如果配置了 loading,我们可以进行管理它。

// 设置请求拦截器
http.interceptors.request.use(
  (request) => {
    if (request.loading) {
      // 如果配置了loading,请求开始需要显示,比如使用全局的loading模块加载
      Tips.loading();
    }
    return request;
  },
  (error) => Promise.resolve(error)
);
// 设置响应拦截器
http.interceptors.response.use(
  (response) => Promise.resolve(response),
  (error) => Promise.reject(error),
  (complete) => {
    if (complete.request.loading) {
      // 如果配置了loading,请求完成需要关闭
      Tips.loaded();
    }
  }
);

比如,我在有题记软考小程序中,是这么使用的

  • 封装一个全局的 loading 组件

  • 使用 uni-http 控制请求接口时的 loading 显示和隐藏

如下图演示效果(文末已给出小程序链接):

loading.gif

四. 支持 upload 上传

前篇文章在写源码的时候并没有单独实现文件上传的功能,因为使用 post 的方式也可以实现文件上传,比如:

http.post("/api/upload", formdata, {
  headers: {
    "Content-Type": "multipart/form-data",
  },
});

其实 uni.uploadFile 的实现方式也是如此,uni-app 的官网对它的定义解释如下:

将本地资源上传到开发者服务器,客户端发起一个 POST 请求,其中 content-type 为 multipart/form-data

如页面通过 uni.chooseImage 等接口获取到一个本地资源的临时文件路径后,可通过此接口将本地资源上传到指定服务器。

uni.chooseImage({
  success: (chooseImageRes) => {
    const tempFilePaths = chooseImageRes.tempFilePaths;
    uni.uploadFile({
      url: "https://www.example.com/api/upload",
      filePath: tempFilePaths[0],
      name: "file",
      formData: {
        user: "admin",
      },
      success: (uploadFileRes) => {
        console.log(uploadFileRes.data);
      },
    });
  },
});

而接下来我们使用官方 uni.uploadFile 方法来实现文件上传,并将它封装到 uni-http 类库中去。

目标:基于 uni.uploadFile,将 uni-http 添加 upload 方法,支持上传文件。

想要实现以上这个目标,我们先来了解下 uni.uploadFile,通过官方文档链接, uni.uploadFile 是将本地资源上传到开发者服务器,客户端发起一个  POST  请求,其中  content-type  为  multipart/form-data

那么,基于以上的了解,我们是否可以使用已有的 POST 请求来实现 uploadFile 呢?

// 如果是上传文件
if (options.method === "upload") {
  url = url && url.indexOf("http") !== 0 ? options.baseURL + url : url;
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url,
      filePath: data.filePath,
      name: data.name,
      formData: data.formData || {},
      success(res) {
        resolve(res);
      },
      fail(e) {
        reject(e);
      },
    });
  });
}

有了以上代码的兼容,uni-http 也支持文件上传的 API,它主要是基于官方 uni.uploadFile 来实现的,因此使用方式和兼容性与官方一致。

接下来我们可以这样来使用文件上传了,这样做的好处是:使用 uploadFile API 可以沿用文章开始已经实例化的 uni-http 的公用配置:

uni.chooseImage({
  success: (chooseImageRes) => {
    const tempFilePaths = chooseImageRes.tempFilePaths;
    http
      .upload("/api/upload", {
        filePath: tempFilePaths[0],
        name: "file",
        formData: {
          user: "admin",
        },
      })
      .then((res) => {
        // 请求成功
      });
  },
});

五. 总结

本篇文章我们主要学习了 uni-http 的相关配置项:

  1. uni-http 支持处理请求的 loading 状态,可以配置选项是否显示 loading,结合请求/响应拦截器进行业务处理显示隐藏状态,进而可以实现接口请求时配置是否显示 loading

  2. 基于 uni.uploadFile,在 uni-http 库中支持 upload 方式,当然,你也可以使用正常的 post 请求实现文件上传。

关联文章

100 行代码打造小而美的 uni-app 请求库(一)

有题记:使用 uni-http 开发的软考刷题小程序

uni-http 官方文档参考