增强你的 axios,分享一个基于 axios 的渐进式请求工具

同学们大家好,忙里偷闲把我在业务中封装的很多请求实用工具分享给大家,为了大家使用方便(也是为了我的开发团队使用方便),我将工具做成了一个库。不占用大家的时间我们直接进入正题,先丢仓库链接,然后介绍这个库是什么东西。 (最近业务压力略大,行文有些潦草,希望大家包涵)

库名: @varlet/axle

github: github.com/varletjs/ax...

设计原则

完全继承 axios 的所有能力,并保留访问 axios 原始对象的能力,不破坏 axios 本身的行为。

介绍

基于 axios 的渐进式请求工具。 它不会破坏 axios 原有的能力,帮助您更轻松地处理请求。

快速开始

安装

shell 复制代码
# 通过 npm, yarn, pnpm 安装

# npm
npm i @varlet/axle -S

#yarn
yarn add @varlet/axle

#pnpm
pnpm add @varlet/axle

发送请求

Axle 归一化了请求函数的参数,并针对不同的业务需求,扩展了更多请求函数,下面是一个简单的例子。

js 复制代码
import { createAxle } from '@varlet/axle'

const axle = createAxle(/** @see https://axios-http.com **/)

axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} })
axle.post('/url', { name: 'Axle' }, { headers: {} })

配置

Axle 完全支持 axios 的所有配置能力。

js 复制代码
const axle = createAxle(/** @see https://axios-http.com **/)
// axle 内置的 axios ,用法和 axios 一模一样,并且和 axle 共享配置。
const { axios } = axle

axios.defaults.baseURL = 'https://api.example.com'
axios.defaults.headers.common['TOKEN'] = TOKEN
axios.defaults.timeout = 2500

// 添加请求前拦截器
axios.interceptors.request.use(
  (config) => {
    // 请求前处理
    return config
  },
  (error) => {
    // 请求错误处理
    return Promise.reject(error)
  }
)

// 添加请求后返回拦截器
axios.interceptors.response.use(
  (response) => {
    // 任何位于 2xx 范围内的状态码都会导致该函数触发
    // 对响应数据做一些事情
    return response
  },
  (error) => {
    // 任何超出 2xx 范围的状态代码都会导致此函数触发
    // 对响应错误做一些事情
    return Promise.reject(error)
  }
)

Axle & Axios 请求函数

Axle 提供的请求函数可以帮助您更轻松地发送请求。 以下是一些示例,包括与 axios 的比较。 提示:下面只是以 getpost 为例,除此之外 Axle 还支持 optionsheaddeletepatchput 方法。

get

JSON

js 复制代码
// axios
axios.get('/url', { params: { id: 1 } })
// axle
axle.get('/url', { id: 1 })

Blob

js 复制代码
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'blob' })
// axle
axle.getBlob('/url', { id: 1 })

Text

js 复制代码
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'text' })
// axle
axle.getText('/url', { id: 1 })

Document

js 复制代码
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'document' })
// axle
axle.getDocument('/url', { id: 1 })

ArrayBuffer

js 复制代码
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' })
// axle
axle.getArrayBuffer('/url', { id: 1 })

Stream

js 复制代码
// axios
axios.get('/url', { params: { id: 1 }, responseType: 'stream' })
// axle
axle.getStream('/url', { id: 1 })

post

JSON

和 axios 一致。

js 复制代码
// axios
axios.post('/url', { name: 'foo' })
// axle
axle.post('/url', { name: 'foo' })

application/x-www-form-urlencoded

js 复制代码
// axios
axios.post('/url', qs.stringify({ name: 'foo' }), {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
})
// axle
axle.postUrlEncode('/url', { name: 'foo' })

multipart/form-data

js 复制代码
// axios
const formData = new FormData()
formData.append('name', 'foo')
formData.append('file', new File())

axios.post('/url', formData, {
  headers: {
    'Content-Type': 'multipart/form-data',
  },
})
// axle
axle.postMultipart('/url', { name: 'foo', file: new File() })

实用工具

通知浏览器下载文件

js 复制代码
import { download } from '@varlet/axle'

download(await axle.getBlob('/url', { id: 1 }), 'filename')

公共 header 操作

js 复制代码
const headers = axle.getHeaders()
axle.setHeader('TOKEN', TOKEN)
axle.removeHeader('TOKEN')

内置拦截器

Axle 提供了一些实用的请求 / 响应拦截器,并且兼容 axle 和 axios,以下是一些使用案例。同时下方总结了一张所有内置拦截器的表格。

axios

ts 复制代码
import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'

const headersInterceptor = requestHeadersInterceptor({
  headers: () => ({
    token: localStorage.getItem('token'),
    'Axle-Custom-Header': 'Axle-Custom-Header',
  })
})

const retryInterceptor = responseRetryInterceptor({ count: 3 })

axios.interceptors.request.use(
  headersInterceptor.onFulfilled, 
  headersInterceptor.onRejected, 
  headersInterceptor.options
)
axios.interceptors.response.use(
  retryInterceptor.onFulfilled,
  retryInterceptor.onRejected, 
  retryInterceptor.options
)

axle

ts 复制代码
import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'

axle.useRequestInterceptor(
  requestHeadersInterceptor({
    headers: () => ({
      token: localStorage.getItem('token'),
      'Axle-Custom-Header': 'Axle-Custom-Header',
    }),
  }),
)

axle.useResponseInterceptor(responseRetryInterceptor({ count: 3 }))

拦截器通用参数 / 拦截器过滤

每个内置拦截器都支持 include exclude axiosInterceptorOptions (与 axios 拦截器一致)

include & exclude

用于请求过滤,以确定什么请求应该应用该拦截器,支持指定 method 或是 glob 语法,使用方式如下。

ts 复制代码
axle.useResponseInterceptor(
  responseRetryInterceptor({ 
    count: 3,
    include: ['method:put', 'method:post'],
    exclude: ['/system/**', '/user/addUser']
  }),
)

内置拦截器一览

名称 描述
requestHeadersInterceptor 用于自定义请求头
requestMockInterceptor 用于模拟数据
responseRetryInterceptor 用于实现请求异常重试
responseStatusInterceptor 用于拦截状态码
responseBlobInterceptor 用于拦截 blob 类型
responseTimeoutInterceptor 用于归一化超时异常

Vue 组合式 API

Axle 提供了 Vue Composition API 风格的用法,封装了请求的 加载状态, 错误状态, 请求的上下行进度返回数据生命周期 等等,并继承了 axios 的所有配置。

html 复制代码
<script setup>
import { createAxle } from '@varlet/axle'
import { createUseAxle } from '@varlet/axle/use'

const axle = createAxle(/** @see https://axios-http.com **/)

const useAxle = createUseAxle({
  axle,
  // 可选项: useAxle 的默认 onTransform
  onTransform: (response) => response,
})

const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort }] = useAxle({
  // 请求初始化数据
  value: [],
  // 请求方法
  method: 'get',
  // 请求地址
  url: '/user',
  // 是否立即发送请求, 默认值: false
  immediate: true,
  // 请求前是否需要重置 value, 默认值: false
  resetValue: true,
  // 请求参数, 默认值: {}
  // 当参数是一个对象时,发送第一个请求(immediate)时将携带它
  // 当参数是一个函数时,每次发送请求时都会携带它。
  params: { current: 1, pageSize: 10 },
  // Axios 配置, see https://axios-http.com
  config: { headers: {} },
  // 生命周期
  onBefore(refs) {
    const { data, loading, error, uploadProgress, downloadProgress } = refs
    console.log(data.value, loading.value, error.value, uploadProgress.value, downloadProgress.value)
    // 处理请求前逻辑
  },
  onTransform(response, refs) {
    // 处理数据转换,转换后的数据将成为 users 的值。
    return response.data
  },
  onSuccess(response, refs) {
    // 处理请求成功逻辑
  },
  onError(error, refs) {
    // 处理请求错误逻辑
  },
  onAfter(refs) {
    // 处理请求结束逻辑,无论成功失败都会触发。
  },
})
</script>

<template>
  <span>{{ users }}</span>
  <span>{{ loading }}</span>
  <span>{{ error }}</span>
  <span>{{ uploadProgress }}</span>
  <span>{{ downloadProgress }}</span>
  <button @click="getUsers">发送请求</button>
  <button @click="abort">中断请求</button>
</template>

并行请求实用工具

Axle 提供了一些并行请求处理工具,请参考以下示例。

html 复制代码
<script setup>
import { createAxle } from '@varlet/axle'
import { createUseAxle, useValues, useAverageProgress, useHasLoading } from '@varlet/axle/use'

const axle = createAxle(/** @see https://axios-http.com **/)

const useAxle = createUseAxle({ axle })

const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({
  value: [],
  method: 'get',
  url: '/user',
})

const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({
  value: [],
  method: 'get',
  url: '/role',
})

// 所有请求结束时,loading 为 false
const loading = useHasLoading(isUsersLoading, isRolesLoading)
// 所有请求结束时,downloadProgress 为 1
const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress)
// Ref<[
//   [{ name: 'foo' }, { name: 'bar' }],
//   [{ role: 'admin' }, { role: 'user' }]
// ]> <-
// [
//   Ref<[{ name: 'foo' }, { name: 'bar' }]>,
//   Ref<[{ role: 'admin' }, { role: 'user' }]>
// ]
const usersRoles = useValues(users, roles)

function sendAllRequest() {
  // parallel
  getUsers()
  getRoles()
}
</script>

<template>
  <span>{{ usersRoles }}</span>
  <span>{{ loading }}</span>
  <span>{{ downloadProgress }}</span>
  <button @click="sendAllRequest">发送全部请求</button>
</template>

结束

希望能对一些同学的工作生活带来便利。

相关推荐
冴羽5 分钟前
SvelteKit 最新中文文档教程(21)—— 最佳实践之图片
前端·javascript·svelte
纪元A梦15 分钟前
华为OD机试真题——跳格子3(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
BillKu36 分钟前
遵守 Vue3 的单向数据流原则:父组件传递对象 + 子组件修改对象属性,安全地实现父子组件之间复杂对象的双向绑定示例代码及讲解
javascript·vue.js·elementui
李鸿耀44 分钟前
Flex布局完全指南,Flexbox 在线演示工具推送
前端·flexbox
涵信1 小时前
第八节:React HooksReact 18+新特性-React Server Components (RSC) 工作原理
前端·react.js·前端框架
林十一npc1 小时前
【Web功能测试】Web商城搜索模块测试用例设计深度解析
前端·测试用例·web测试·搜索框·商城测试
小p1 小时前
迈向全栈:服务器上的软件安装
前端·后端
凯哥19702 小时前
Sciter.js 新手指南-GUI开发中的窗口使用指南
前端
Nuyoah.2 小时前
《vue3学习手记3》
前端·javascript·vue.js·学习·前端框架
最新资讯动态2 小时前
首发即燃!《群星纪元》携手鲸鸿动能引领科幻热潮,打造爆款国产SLG手游
前端