一分钟完成 axios 各种功能实现(取消重复请求、缓存数据、响应包装等)

3,777 阅读2分钟

推荐使用新工具

重新定义 Axios 的使用方式

前言

✨ 相信各位道友对前端工具里的 axios 都不陌生了,本文给大家分享如何能够快速实现对 axios 功能的扩展!

创建示例项目

vite + vue3 那么火当然是主选了😁

# 使用 pnpm 创建 vue-ts 项目
pnpm create vite test-app -- --template vue-ts

安装依赖

注意:需进入项目根目录再安装依赖!

pnpm i # 安装项目依赖
pnpm add axios @iel/axios-ext @iel/axios-ext-preset # 安装 axios 相关工具

扩展 axios

// src/services/http.ts
import { createAxios } from '@iel/axios-ext'
import TupleWrapper, { AxiosResponseTuple } from '@iel/axios-ext-response-wrap/dist/wrappers/tuple'
import { ErrorAdaptor, SuccessAdaptor } from '@iel/axios-ext-response-wrap/dist/adaptors'
import usePresetForAxiosExt from '@iel/axios-ext-preset'

declare module 'axios' {
  // 修改响应结果为元祖
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
  interface AxiosResponse<T = any, D = any> extends AxiosResponseTuple<T, D> {}
}

// 创建 axios 实例
export const http = createAxios({
  baseURL: '/api',
  timeout: 5000
})

// 手动取消类型
const MANUAL_CANCEL = 'manualCancel'

// 可用于判断接口是否为主动取消,从而中断后续操作
export const isManualCancel = (value: string) => value === MANUAL_CANCEL

function initExt() {
  // 元祖响应格式包装器
  // adaptor 为数据适配器,处理后端返回数据格式,多个时将一一匹配
  const tupleWrapper = TupleWrapper([ErrorAdaptor, SuccessAdaptor])

  // 为 axiosExt 预设插件,将会对 axios 实例进行功能扩展
  usePresetForAxiosExt(http.$axiosExt, {
    // 配置缓存功能
    Cache: {
      // 当缓存有效时需要返回的数据
      transformData: (response, config) => tupleWrapper.transformResponseData(response, config),
      // 当响应成功时判断是否需要缓存数据
      // 通过元祖包装器转换成元祖后判断接口是否成功
      allowCache: (response, config) => !tupleWrapper.transformResponseData(response, config)[0]
    },
    // 配置取消重复请求
    CancelRepeat: {
      // 手动取消时需要返回的消息
      manualCancelMessage: MANUAL_CANCEL,
      // 当请求重复时需要返回的数据,这里返回元祖,与响应包装结果相对应
      onRepeat: () => [true, MANUAL_CANCEL]
    },
    // 配置响应包装
    ResponseWrap: {
      // 设置数据包装器
      wrapper: tupleWrapper
    }
  })
}

initExt()

通过以上代码我们就完成了对 axios 的功能扩展,其中包括:数据缓存、重复取消、插件日志、响应包装、失败重连。

测试页面 (iel-h.github.io)

自动携带 token 插件

上面是我们使用预设插件对 axios 进行扩展,虽然很快,但若需要其他功能又该怎么办呢?

这里教给大家如何自己实现一个插件的封装和使用!

// src/services/plugins/auto-add-token.ts
import { onRequest } from '@iel/axios-ext'

// 插件初始化时会传入 axiosExt 实例以及插件所需的配置项
export default function autoAddToken(axiosExt, opts = {}) {
  // 在请求阶段时修改 config 配置项为其添加 token
  onRequest(({ config }) => {
    config.headers ??= {}
    config.headers.Authorization = localStorage.token || ''
  })
}

注册我们开发的插件!

// src/services/http.ts
import AutoAddTokenPlugin from './plugins/auto-add-token'

// ...

http.$axiosExt.use(AutoAddTokenPlugin)

之后我们使用 http 请求时就可以看到会自动携带上 token 了!

结束

以上就是项目中对 axios 快速扩展的实现方式,在公司内部也可自行封装相关插件发布私服上,后续就可以便于使用和维护了!

相关链接