@varlet/axle 0.13.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -529
- package/README.zh-CN.md +33 -529
- package/lib/index.cjs +0 -21
- package/lib/index.d.cts +1 -9
- package/lib/index.d.ts +1 -9
- package/lib/index.js +0 -20
- package/lib/use.cjs +16 -66
- package/lib/use.d.cts +2 -8
- package/lib/use.d.ts +2 -8
- package/lib/use.js +9 -56
- package/package.json +2 -2
package/README.zh-CN.md
CHANGED
|
@@ -1,30 +1,49 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://axle.varletjs.org">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/varletjs/axle/main/packages/docs/public/logo.svg" width="150">
|
|
4
|
+
</a>
|
|
5
|
+
<h1>AXLE</h1>
|
|
6
|
+
<p>基于 axios 的渐进式请求工具。</p>
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://axle.varletjs.org">文档</a> |
|
|
9
|
+
<a href="https://github.com/varletjs/axle/blob/main/README.md">ENGLISH README</a>
|
|
10
|
+
</p>
|
|
11
|
+
<p>
|
|
12
|
+
<img src="https://img.shields.io/npm/v/@varlet/axle?style=flat-square" alt="version">
|
|
13
|
+
<img src="https://img.shields.io/github/stars/varletjs/axle" alt="stars">
|
|
14
|
+
<img src="https://img.shields.io/badge/vue-v3.2.0%2B-%23407fbc" alt="vue">
|
|
15
|
+
<img src="https://img.shields.io/npm/l/@varlet/axle.svg" alt="license">
|
|
16
|
+
</p>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
3
20
|
|
|
4
21
|
### 介绍
|
|
5
22
|
|
|
6
|
-
基于 [axios](https://axios-http.com/)
|
|
23
|
+
基于 [axios](https://axios-http.com/) 的渐进式请求工具。它不会破坏 `axios` 原有的能力,帮助您更轻松地处理请求。
|
|
7
24
|
|
|
8
|
-
###
|
|
25
|
+
### 特性
|
|
9
26
|
|
|
10
|
-
|
|
27
|
+
- 🚀 归一化请求函数参数,并扩展了不同响应类型的请求方法
|
|
28
|
+
- 💪 支持 Vue 组合式 API,封装了加载状态、错误状态、上传下载进度、生命周期等
|
|
29
|
+
- 🛠️ 内置实用的请求/响应拦截器
|
|
30
|
+
- 💡 通过 `createApi` 增强 API 定义能力
|
|
31
|
+
- 🌍 完全兼容 axios 配置
|
|
11
32
|
|
|
12
|
-
|
|
13
|
-
# 通过 npm, yarn, pnpm 安装
|
|
33
|
+
### 安装
|
|
14
34
|
|
|
35
|
+
```shell
|
|
15
36
|
# npm
|
|
16
37
|
npm i @varlet/axle -S
|
|
17
38
|
|
|
18
|
-
#yarn
|
|
39
|
+
# yarn
|
|
19
40
|
yarn add @varlet/axle
|
|
20
41
|
|
|
21
|
-
#pnpm
|
|
42
|
+
# pnpm
|
|
22
43
|
pnpm add @varlet/axle
|
|
23
44
|
```
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
`Axle` 归一化了请求函数的参数,并针对不同的业务需求,扩展了更多请求函数,下面是一个简单的例子。
|
|
46
|
+
### 基本用法
|
|
28
47
|
|
|
29
48
|
```js
|
|
30
49
|
import { createAxle } from '@varlet/axle'
|
|
@@ -35,521 +54,6 @@ axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} })
|
|
|
35
54
|
axle.post('/url', { name: 'Axle' }, { headers: {} })
|
|
36
55
|
```
|
|
37
56
|
|
|
38
|
-
###
|
|
39
|
-
|
|
40
|
-
`Axle` 完全支持 `axios` 的所有配置能力。
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
44
|
-
// axle 内置的 axios ,用法和 axios 一模一样,并且和 axle 共享配置。
|
|
45
|
-
const { axios } = axle
|
|
46
|
-
|
|
47
|
-
axios.defaults.baseURL = 'https://api.example.com'
|
|
48
|
-
axios.defaults.headers.common['TOKEN'] = TOKEN
|
|
49
|
-
axios.defaults.timeout = 2500
|
|
50
|
-
|
|
51
|
-
// 添加请求前拦截器
|
|
52
|
-
axios.interceptors.request.use(
|
|
53
|
-
(config) => {
|
|
54
|
-
// 请求前处理
|
|
55
|
-
return config
|
|
56
|
-
},
|
|
57
|
-
(error) => {
|
|
58
|
-
// 请求错误处理
|
|
59
|
-
return Promise.reject(error)
|
|
60
|
-
},
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
// 添加请求后返回拦截器
|
|
64
|
-
axios.interceptors.response.use(
|
|
65
|
-
(response) => {
|
|
66
|
-
// 任何位于 2xx 范围内的状态码都会导致该函数触发
|
|
67
|
-
// 对响应数据做一些事情
|
|
68
|
-
return response
|
|
69
|
-
},
|
|
70
|
-
(error) => {
|
|
71
|
-
// 任何超出 2xx 范围的状态代码都会导致此函数触发
|
|
72
|
-
// 对响应错误做一些事情
|
|
73
|
-
return Promise.reject(error)
|
|
74
|
-
},
|
|
75
|
-
)
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Axle & Axios 请求函数
|
|
79
|
-
|
|
80
|
-
`Axle` 提供的请求函数可以帮助您更轻松地发送请求。 以下是一些示例,包括与 `axios` 的比较。
|
|
81
|
-
提示:下面只是以 `get` 和 `post` 为例,除此之外 Axle 还支持 `options`、`head`、`delete`、`patch` 、`put` 方法。
|
|
82
|
-
|
|
83
|
-
### get
|
|
84
|
-
|
|
85
|
-
#### JSON
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
// axios
|
|
89
|
-
axios.get('/url', { params: { id: 1 } })
|
|
90
|
-
// axle
|
|
91
|
-
axle.get('/url', { id: 1 })
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
#### Blob
|
|
95
|
-
|
|
96
|
-
```js
|
|
97
|
-
// axios
|
|
98
|
-
axios.get('/url', { params: { id: 1 }, responseType: 'blob' })
|
|
99
|
-
// axle
|
|
100
|
-
axle.getBlob('/url', { id: 1 })
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### Text
|
|
104
|
-
|
|
105
|
-
```js
|
|
106
|
-
// axios
|
|
107
|
-
axios.get('/url', { params: { id: 1 }, responseType: 'text' })
|
|
108
|
-
// axle
|
|
109
|
-
axle.getText('/url', { id: 1 })
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
#### Document
|
|
113
|
-
|
|
114
|
-
```js
|
|
115
|
-
// axios
|
|
116
|
-
axios.get('/url', { params: { id: 1 }, responseType: 'document' })
|
|
117
|
-
// axle
|
|
118
|
-
axle.getDocument('/url', { id: 1 })
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
#### ArrayBuffer
|
|
122
|
-
|
|
123
|
-
```js
|
|
124
|
-
// axios
|
|
125
|
-
axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' })
|
|
126
|
-
// axle
|
|
127
|
-
axle.getArrayBuffer('/url', { id: 1 })
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
#### Stream
|
|
131
|
-
|
|
132
|
-
```js
|
|
133
|
-
// axios
|
|
134
|
-
axios.get('/url', { params: { id: 1 }, responseType: 'stream' })
|
|
135
|
-
// axle
|
|
136
|
-
axle.getStream('/url', { id: 1 })
|
|
137
|
-
```
|
|
57
|
+
### 文档
|
|
138
58
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
#### JSON
|
|
142
|
-
|
|
143
|
-
和 axios 一致。
|
|
144
|
-
|
|
145
|
-
```js
|
|
146
|
-
// axios
|
|
147
|
-
axios.post('/url', { name: 'foo' })
|
|
148
|
-
// axle
|
|
149
|
-
axle.post('/url', { name: 'foo' })
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
#### application/x-www-form-urlencoded
|
|
153
|
-
|
|
154
|
-
```js
|
|
155
|
-
// axios
|
|
156
|
-
axios.post('/url', qs.stringify({ name: 'foo' }), {
|
|
157
|
-
headers: {
|
|
158
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
159
|
-
},
|
|
160
|
-
})
|
|
161
|
-
// axle
|
|
162
|
-
axle.postUrlEncode('/url', { name: 'foo' })
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
#### multipart/form-data
|
|
166
|
-
|
|
167
|
-
```js
|
|
168
|
-
// axios
|
|
169
|
-
const formData = new FormData()
|
|
170
|
-
formData.append('name', 'foo')
|
|
171
|
-
formData.append('file', new File())
|
|
172
|
-
|
|
173
|
-
axios.post('/url', formData, {
|
|
174
|
-
headers: {
|
|
175
|
-
'Content-Type': 'multipart/form-data',
|
|
176
|
-
},
|
|
177
|
-
})
|
|
178
|
-
// axle
|
|
179
|
-
axle.postMultipart('/url', { name: 'foo', file: new File() })
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## 实用工具
|
|
183
|
-
|
|
184
|
-
#### 通知浏览器下载文件
|
|
185
|
-
|
|
186
|
-
```js
|
|
187
|
-
import { download } from '@varlet/axle'
|
|
188
|
-
|
|
189
|
-
download(await axle.getBlob('/url', { id: 1 }), 'filename')
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
#### 同时返回成功响应和错误响应
|
|
193
|
-
|
|
194
|
-
```js
|
|
195
|
-
import { withResponse } from '@varlet/axle'
|
|
196
|
-
|
|
197
|
-
const { response, errorResponse } = await withResponse(axle.get('/url'))
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### 公共 header 操作
|
|
201
|
-
|
|
202
|
-
```js
|
|
203
|
-
const headers = axle.getHeaders()
|
|
204
|
-
axle.setHeader('TOKEN', TOKEN)
|
|
205
|
-
axle.removeHeader('TOKEN')
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## 内置拦截器
|
|
209
|
-
|
|
210
|
-
Axle 提供了一些实用的请求/响应拦截器,并且兼容 axle 和 axios。
|
|
211
|
-
|
|
212
|
-
### axios
|
|
213
|
-
|
|
214
|
-
```ts
|
|
215
|
-
import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'
|
|
216
|
-
|
|
217
|
-
const headersInterceptor = requestHeadersInterceptor({
|
|
218
|
-
headers: () => ({
|
|
219
|
-
token: localStorage.getItem('token'),
|
|
220
|
-
'Axle-Custom-Header': 'Axle-Custom-Header',
|
|
221
|
-
}),
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
const retryInterceptor = responseRetryInterceptor({ count: 3 })
|
|
225
|
-
|
|
226
|
-
axios.interceptors.request.use(
|
|
227
|
-
headersInterceptor.onFulfilled,
|
|
228
|
-
headersInterceptor.onRejected,
|
|
229
|
-
headersInterceptor.options,
|
|
230
|
-
)
|
|
231
|
-
axios.interceptors.response.use(retryInterceptor.onFulfilled, retryInterceptor.onRejected, retryInterceptor.options)
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### axle
|
|
235
|
-
|
|
236
|
-
```ts
|
|
237
|
-
import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'
|
|
238
|
-
|
|
239
|
-
axle.useRequestInterceptor(
|
|
240
|
-
requestHeadersInterceptor({
|
|
241
|
-
headers: () => ({
|
|
242
|
-
token: localStorage.getItem('token'),
|
|
243
|
-
'Axle-Custom-Header': 'Axle-Custom-Header',
|
|
244
|
-
}),
|
|
245
|
-
}),
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
axle.useResponseInterceptor(responseRetryInterceptor({ count: 3 }))
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### 拦截器通用参数
|
|
252
|
-
|
|
253
|
-
每个内置拦截器都支持 `include` `exclude` `axiosInterceptorOptions (与 axios 拦截器一致)`。
|
|
254
|
-
|
|
255
|
-
#### include & exclude
|
|
256
|
-
|
|
257
|
-
用于请求过滤,以确定什么请求应该应用该拦截器,支持指定 `method`、 `glob` 或者 `status`,使用方式如下。
|
|
258
|
-
|
|
259
|
-
```ts
|
|
260
|
-
axle.useResponseInterceptor(
|
|
261
|
-
responseRetryInterceptor({
|
|
262
|
-
count: 3,
|
|
263
|
-
include: ['method:put', 'method:post', 'status:500'],
|
|
264
|
-
exclude: ['/system/**', '/user/addUser', 'status:400'],
|
|
265
|
-
}),
|
|
266
|
-
)
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### 内置拦截器一览
|
|
270
|
-
|
|
271
|
-
| 名称 | 描述 |
|
|
272
|
-
| ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
|
273
|
-
| [requestHeadersInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestHeadersInterceptor.md) | 用于自定义请求头 |
|
|
274
|
-
| [requestMockInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestMockInterceptor.md) | 用于模拟数据 |
|
|
275
|
-
| [requestMd5Interceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestMd5Interceptor.md) | 用于对请求参数进行 md5 处理 |
|
|
276
|
-
| [responseRetryInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseRetryInterceptor.md) | 用于实现请求异常重试 |
|
|
277
|
-
| [responseStatusInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseStatusInterceptor.md) | 用于拦截状态码 |
|
|
278
|
-
| [responseBlobInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseBlobInterceptor.md) | 用于拦截 blob 类型 |
|
|
279
|
-
| [responseTimeoutInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseTimeoutInterceptor.md) | 用于归一化超时异常 |
|
|
280
|
-
|
|
281
|
-
## Vue 组合式 API
|
|
282
|
-
|
|
283
|
-
Axle 提供了 Vue Composition API 风格的用法,封装了请求的 `加载状态`, `错误状态`, `请求的上下行进度`,`返回数据`,`生命周期` 等等,并继承了 `axios` 的所有配置。
|
|
284
|
-
|
|
285
|
-
```html
|
|
286
|
-
<script setup>
|
|
287
|
-
import { createAxle } from '@varlet/axle'
|
|
288
|
-
import { createUseAxle } from '@varlet/axle/use'
|
|
289
|
-
|
|
290
|
-
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
291
|
-
|
|
292
|
-
const useAxle = createUseAxle({
|
|
293
|
-
axle,
|
|
294
|
-
// 可选项: useAxle 的默认 immediate, 默认值: true
|
|
295
|
-
immediate: false,
|
|
296
|
-
// 可选项: useAxle 的默认 onTransform
|
|
297
|
-
onTransform: (response) => response,
|
|
298
|
-
})
|
|
299
|
-
|
|
300
|
-
const id = ref('1')
|
|
301
|
-
|
|
302
|
-
const [
|
|
303
|
-
users,
|
|
304
|
-
// 请求触发器
|
|
305
|
-
getUsers,
|
|
306
|
-
// 附加属性
|
|
307
|
-
{ loading, error, uploadProgress, downloadProgress, abort },
|
|
308
|
-
] = useAxle({
|
|
309
|
-
// 请求初始化数据
|
|
310
|
-
value: [],
|
|
311
|
-
// 请求方法
|
|
312
|
-
method: 'get',
|
|
313
|
-
// 请求地址, 可以是 getter 函数
|
|
314
|
-
url: '/user',
|
|
315
|
-
// 是否立即发送请求, 默认值: true
|
|
316
|
-
immediate: false,
|
|
317
|
-
// 监听响应式参数变化时自动重新加载
|
|
318
|
-
// 设置为 true 时,监听所有参数变化 (params, config, pathParams)
|
|
319
|
-
// 设置为对象时,监听指定参数变化:
|
|
320
|
-
// - params: true - 监听 params 参数变化
|
|
321
|
-
// - pathParams: true - 监听 pathParams 变化(用于 API 定义)
|
|
322
|
-
// - config: true - 监听 config 配置变化
|
|
323
|
-
watch: true,
|
|
324
|
-
// 请求前是否需要重置 value, 默认值: false
|
|
325
|
-
resetValue: true,
|
|
326
|
-
// 重置 value 是否对 value 进行拷贝
|
|
327
|
-
// 设置为 true 时, 使用 JSON.parse(JSON.stringify(value)) 进行拷贝
|
|
328
|
-
// 设置为一个函数时, 该函数将作为拷贝函数对 value 进行拷贝, 如 v => _.cloneDeep(v)
|
|
329
|
-
cloneResetValue: true,
|
|
330
|
-
// 请求参数, 默认值: {}, 可以是 getter 函数
|
|
331
|
-
params: { current: 1, pageSize: 10 },
|
|
332
|
-
// Axios 配置, see https://axios-http.com, 可以是 getter 函数
|
|
333
|
-
config: { headers: {} },
|
|
334
|
-
// 生命周期
|
|
335
|
-
onBefore(refs) {
|
|
336
|
-
const { data, loading, error, uploadProgress, downloadProgress } = refs
|
|
337
|
-
console.log(data.value, loading.value, error.value, uploadProgress.value, downloadProgress.value)
|
|
338
|
-
// 处理请求前逻辑
|
|
339
|
-
},
|
|
340
|
-
onTransform(response, refs) {
|
|
341
|
-
// 处理数据转换,转换后的数据将成为 users 的值。
|
|
342
|
-
return response.data
|
|
343
|
-
},
|
|
344
|
-
onSuccess(response, refs) {
|
|
345
|
-
// 处理请求成功逻辑
|
|
346
|
-
},
|
|
347
|
-
onError(error, refs) {
|
|
348
|
-
// 处理请求错误逻辑
|
|
349
|
-
},
|
|
350
|
-
onAfter(refs) {
|
|
351
|
-
// 处理请求结束逻辑,无论成功失败都会触发。
|
|
352
|
-
},
|
|
353
|
-
})
|
|
354
|
-
</script>
|
|
355
|
-
|
|
356
|
-
<template>
|
|
357
|
-
<span>{{ users }}</span>
|
|
358
|
-
<span>{{ loading }}</span>
|
|
359
|
-
<span>{{ error }}</span>
|
|
360
|
-
<span>{{ uploadProgress }}</span>
|
|
361
|
-
<span>{{ downloadProgress }}</span>
|
|
362
|
-
<button @click="getUsers">发送请求</button>
|
|
363
|
-
<button @click="abort">中断请求</button>
|
|
364
|
-
</template>
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### 并行请求实用工具
|
|
368
|
-
|
|
369
|
-
Axle 提供了一些并行请求处理工具,请参考以下示例。
|
|
370
|
-
|
|
371
|
-
```html
|
|
372
|
-
<script setup>
|
|
373
|
-
import { createAxle } from '@varlet/axle'
|
|
374
|
-
import { createUseAxle, useAverageProgress, useHasLoading, useValues } from '@varlet/axle/use'
|
|
375
|
-
|
|
376
|
-
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
377
|
-
|
|
378
|
-
const useAxle = createUseAxle({ axle })
|
|
379
|
-
|
|
380
|
-
const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({
|
|
381
|
-
method: 'get',
|
|
382
|
-
url: '/user',
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({
|
|
386
|
-
method: 'get',
|
|
387
|
-
url: '/role',
|
|
388
|
-
})
|
|
389
|
-
|
|
390
|
-
// 所有请求结束时,loading 为 false
|
|
391
|
-
const loading = useHasLoading(isUsersLoading, isRolesLoading)
|
|
392
|
-
// 所有请求结束时,downloadProgress 为 1
|
|
393
|
-
const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress)
|
|
394
|
-
// Ref<[
|
|
395
|
-
// [{ name: 'foo' }, { name: 'bar' }],
|
|
396
|
-
// [{ role: 'admin' }, { role: 'user' }]
|
|
397
|
-
// ]> <-
|
|
398
|
-
// [
|
|
399
|
-
// Ref<[{ name: 'foo' }, { name: 'bar' }]>,
|
|
400
|
-
// Ref<[{ role: 'admin' }, { role: 'user' }]>
|
|
401
|
-
// ]
|
|
402
|
-
const usersRoles = useValues(users, roles)
|
|
403
|
-
|
|
404
|
-
function sendAllRequest() {
|
|
405
|
-
// parallel
|
|
406
|
-
getUsers()
|
|
407
|
-
getRoles()
|
|
408
|
-
}
|
|
409
|
-
</script>
|
|
410
|
-
|
|
411
|
-
<template>
|
|
412
|
-
<span>{{ usersRoles }}</span>
|
|
413
|
-
<span>{{ loading }}</span>
|
|
414
|
-
<span>{{ downloadProgress }}</span>
|
|
415
|
-
<button @click="sendAllRequest">发送全部请求</button>
|
|
416
|
-
</template>
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
### API 定义增强
|
|
420
|
-
|
|
421
|
-
从 `0.9.0` 开始支持 `createApi`,以增强 API 定义能力。
|
|
422
|
-
|
|
423
|
-
#### 定义 API
|
|
424
|
-
|
|
425
|
-
```ts
|
|
426
|
-
import { createAxle } from '@varlet/axle'
|
|
427
|
-
import { createApi } from '@varlet/axle/api'
|
|
428
|
-
import { createUseAxle } from '@varlet/axle/use'
|
|
429
|
-
|
|
430
|
-
const axle = createAxle({
|
|
431
|
-
baseURL: '/api',
|
|
432
|
-
})
|
|
433
|
-
|
|
434
|
-
const useAxle = createUseAxle({
|
|
435
|
-
axle,
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
const api = createApi(axle, useAxle)
|
|
439
|
-
|
|
440
|
-
export const apiGetUsers = api<Response<User[]>>('/user', 'get')
|
|
441
|
-
|
|
442
|
-
export const apiGetUser = api<Response<User>>('/user/:id', 'get')
|
|
443
|
-
|
|
444
|
-
export const apiCreateUser = api<Response<User>, CreateUser>('/user', 'post')
|
|
445
|
-
|
|
446
|
-
export const apiUpdateUser = api<Response<User>, UpdateUser>('/user/:id', 'put')
|
|
447
|
-
|
|
448
|
-
export const apiDeleteUser = api<Response<User>>('/user/:id', 'delete')
|
|
449
|
-
|
|
450
|
-
export type Response<T> = {
|
|
451
|
-
data: T
|
|
452
|
-
code: number
|
|
453
|
-
message: string
|
|
454
|
-
success: boolean
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
export interface User {
|
|
458
|
-
id: string
|
|
459
|
-
name: string
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
export interface CreateUser {
|
|
463
|
-
name: string
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
export interface UpdateUser {
|
|
467
|
-
name: string
|
|
468
|
-
}
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
#### 调用 API
|
|
472
|
-
|
|
473
|
-
```ts
|
|
474
|
-
const route = useRoute()
|
|
475
|
-
|
|
476
|
-
const [users, getUsers] = apiGetUsers.use<Response<User[]>>(/** 和 useAxle 一致并且扩展了 pathParams **/)
|
|
477
|
-
|
|
478
|
-
const [user, getUser] = apiGetUser.use<Response<User>>({
|
|
479
|
-
pathParams: () => ({ id: route.params.id }),
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
async function handleCreate(params: CreateUser) {
|
|
483
|
-
const { success } = await apiCreateUser.load(params)
|
|
484
|
-
|
|
485
|
-
if (success) {
|
|
486
|
-
getUsers()
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
async function handleUpdate(params: UpdateUser, id: string) {
|
|
491
|
-
const { success } = await apiUpdateUser.load(params, { id })
|
|
492
|
-
|
|
493
|
-
if (success) {
|
|
494
|
-
getUsers()
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
async function handleDelete(id: string) {
|
|
499
|
-
const { success } = await apiDeleteUser.load({}, { id })
|
|
500
|
-
|
|
501
|
-
if (success) {
|
|
502
|
-
getUsers()
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
### 请求触发器增强
|
|
508
|
-
|
|
509
|
-
从 `v0.10.0` 开始, 请求触发器将包含附加属性中的全部属性。
|
|
510
|
-
|
|
511
|
-
增强前:
|
|
512
|
-
|
|
513
|
-
```html
|
|
514
|
-
<script setup>
|
|
515
|
-
const [users, getUsers, { loading: isUsersLoading }] = useAxle({
|
|
516
|
-
method: 'get',
|
|
517
|
-
url: '/user',
|
|
518
|
-
})
|
|
519
|
-
|
|
520
|
-
const [posts, getPosts, { loading: isPostsLoading }] = useAxle({
|
|
521
|
-
method: 'get',
|
|
522
|
-
url: '/post',
|
|
523
|
-
})
|
|
524
|
-
</script>
|
|
525
|
-
|
|
526
|
-
<template>
|
|
527
|
-
<span>{{ isUsersLoading ? 'loading...' : users }}</span>
|
|
528
|
-
<span>{{ isPostsLoading ? 'loading...' : posts }}</span>
|
|
529
|
-
<button @click="getUsers">Send Request</button>
|
|
530
|
-
<button @click="getPosts">Send Request</button>
|
|
531
|
-
</template>
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
增强后:
|
|
535
|
-
|
|
536
|
-
```html
|
|
537
|
-
<script setup>
|
|
538
|
-
const [users, getUsers] = useAxle({
|
|
539
|
-
method: 'get',
|
|
540
|
-
url: '/user',
|
|
541
|
-
})
|
|
542
|
-
|
|
543
|
-
const [posts, getPosts] = useAxle({
|
|
544
|
-
method: 'get',
|
|
545
|
-
url: '/post',
|
|
546
|
-
})
|
|
547
|
-
</script>
|
|
548
|
-
|
|
549
|
-
<template>
|
|
550
|
-
<span>{{ getUsers.loading.value ? 'loading...' : users }}</span>
|
|
551
|
-
<span>{{ getPosts.loading.value ? 'loading...' : posts }}</span>
|
|
552
|
-
<button @click="getUsers">Send Request</button>
|
|
553
|
-
<button @click="getPosts">Send Request</button>
|
|
554
|
-
</template>
|
|
555
|
-
```
|
|
59
|
+
完整文档请访问[文档站](https://axle.varletjs.org)。
|
package/lib/index.cjs
CHANGED
|
@@ -61,7 +61,6 @@ __export(src_exports, {
|
|
|
61
61
|
responseBlobInterceptor: () => responseBlobInterceptor,
|
|
62
62
|
responseRetryInterceptor: () => responseRetryInterceptor,
|
|
63
63
|
responseStatusInterceptor: () => responseStatusInterceptor,
|
|
64
|
-
responseTimeoutInterceptor: () => responseTimeoutInterceptor,
|
|
65
64
|
withResponse: () => withResponse
|
|
66
65
|
});
|
|
67
66
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -347,25 +346,6 @@ function responseBlobInterceptor(options = {}) {
|
|
|
347
346
|
};
|
|
348
347
|
}
|
|
349
348
|
|
|
350
|
-
// src/interceptors/responseTimeoutInterceptor.ts
|
|
351
|
-
function responseTimeoutInterceptor(options = {}) {
|
|
352
|
-
return {
|
|
353
|
-
onFulfilled: (response) => response,
|
|
354
|
-
onRejected(error) {
|
|
355
|
-
var _a, _b, _c, _d;
|
|
356
|
-
const matcher = createMatcher(options.include, options.exclude);
|
|
357
|
-
if (!matcher((_a = error.config.method) != null ? _a : "", (_b = error.config.url) != null ? _b : "", (_c = error == null ? void 0 : error.response) == null ? void 0 : _c.status)) {
|
|
358
|
-
return Promise.reject(error);
|
|
359
|
-
}
|
|
360
|
-
if (error.code === "ECONNABORTED" && error.message.includes("timeout") || error.code === "ETIMEDOUT") {
|
|
361
|
-
error.code = (_d = options == null ? void 0 : options.normalizeErrorCode) != null ? _d : "TIMEOUT";
|
|
362
|
-
}
|
|
363
|
-
return Promise.reject(error);
|
|
364
|
-
},
|
|
365
|
-
options: options.axiosInterceptorOptions
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
349
|
// src/interceptors/responseRetryInterceptor.ts
|
|
370
350
|
var import_axios5 = __toESM(require("axios"), 1);
|
|
371
351
|
function responseRetryInterceptor(options) {
|
|
@@ -506,6 +486,5 @@ function requestMd5Interceptor(options = {}) {
|
|
|
506
486
|
responseBlobInterceptor,
|
|
507
487
|
responseRetryInterceptor,
|
|
508
488
|
responseStatusInterceptor,
|
|
509
|
-
responseTimeoutInterceptor,
|
|
510
489
|
withResponse
|
|
511
490
|
});
|
package/lib/index.d.cts
CHANGED
|
@@ -52,14 +52,6 @@ interface ResponseBlobInterceptorOptions {
|
|
|
52
52
|
}
|
|
53
53
|
declare function responseBlobInterceptor(options?: ResponseBlobInterceptorOptions): ResponseInterceptor;
|
|
54
54
|
|
|
55
|
-
interface ResponseTimeoutInterceptorOptions {
|
|
56
|
-
normalizeErrorCode?: string;
|
|
57
|
-
include?: MatchPattern[];
|
|
58
|
-
exclude?: MatchPattern[];
|
|
59
|
-
axiosInterceptorOptions?: AxiosInterceptorOptions;
|
|
60
|
-
}
|
|
61
|
-
declare function responseTimeoutInterceptor(options?: ResponseTimeoutInterceptorOptions): ResponseInterceptor;
|
|
62
|
-
|
|
63
55
|
interface ResponseRetryInterceptorOptions {
|
|
64
56
|
count?: number;
|
|
65
57
|
include?: MatchPattern[];
|
|
@@ -90,4 +82,4 @@ interface RequestMd5InterceptorOptions {
|
|
|
90
82
|
}
|
|
91
83
|
declare function requestMd5Interceptor(options?: RequestMd5InterceptorOptions): RequestInterceptor;
|
|
92
84
|
|
|
93
|
-
export { MatchPattern, RequestHeadersInterceptorOptions, RequestInterceptor, RequestMd5InterceptorMapping, RequestMd5InterceptorOptions, RequestMockInterceptorMapping, RequestMockInterceptorOptions, ResponseBlobInterceptorOptions, ResponseInterceptor, ResponseRetryInterceptorOptions, ResponseStatusInterceptorOptions,
|
|
85
|
+
export { MatchPattern, RequestHeadersInterceptorOptions, RequestInterceptor, RequestMd5InterceptorMapping, RequestMd5InterceptorOptions, RequestMockInterceptorMapping, RequestMockInterceptorOptions, ResponseBlobInterceptorOptions, ResponseInterceptor, ResponseRetryInterceptorOptions, ResponseStatusInterceptorOptions, WithResponseReturn, createMatcher, download, matchPattern, requestHeadersInterceptor, requestMd5Interceptor, requestMockInterceptor, responseBlobInterceptor, responseRetryInterceptor, responseStatusInterceptor, withResponse };
|
package/lib/index.d.ts
CHANGED
|
@@ -52,14 +52,6 @@ interface ResponseBlobInterceptorOptions {
|
|
|
52
52
|
}
|
|
53
53
|
declare function responseBlobInterceptor(options?: ResponseBlobInterceptorOptions): ResponseInterceptor;
|
|
54
54
|
|
|
55
|
-
interface ResponseTimeoutInterceptorOptions {
|
|
56
|
-
normalizeErrorCode?: string;
|
|
57
|
-
include?: MatchPattern[];
|
|
58
|
-
exclude?: MatchPattern[];
|
|
59
|
-
axiosInterceptorOptions?: AxiosInterceptorOptions;
|
|
60
|
-
}
|
|
61
|
-
declare function responseTimeoutInterceptor(options?: ResponseTimeoutInterceptorOptions): ResponseInterceptor;
|
|
62
|
-
|
|
63
55
|
interface ResponseRetryInterceptorOptions {
|
|
64
56
|
count?: number;
|
|
65
57
|
include?: MatchPattern[];
|
|
@@ -90,4 +82,4 @@ interface RequestMd5InterceptorOptions {
|
|
|
90
82
|
}
|
|
91
83
|
declare function requestMd5Interceptor(options?: RequestMd5InterceptorOptions): RequestInterceptor;
|
|
92
84
|
|
|
93
|
-
export { MatchPattern, RequestHeadersInterceptorOptions, RequestInterceptor, RequestMd5InterceptorMapping, RequestMd5InterceptorOptions, RequestMockInterceptorMapping, RequestMockInterceptorOptions, ResponseBlobInterceptorOptions, ResponseInterceptor, ResponseRetryInterceptorOptions, ResponseStatusInterceptorOptions,
|
|
85
|
+
export { MatchPattern, RequestHeadersInterceptorOptions, RequestInterceptor, RequestMd5InterceptorMapping, RequestMd5InterceptorOptions, RequestMockInterceptorMapping, RequestMockInterceptorOptions, ResponseBlobInterceptorOptions, ResponseInterceptor, ResponseRetryInterceptorOptions, ResponseStatusInterceptorOptions, WithResponseReturn, createMatcher, download, matchPattern, requestHeadersInterceptor, requestMd5Interceptor, requestMockInterceptor, responseBlobInterceptor, responseRetryInterceptor, responseStatusInterceptor, withResponse };
|
package/lib/index.js
CHANGED
|
@@ -284,25 +284,6 @@ function responseBlobInterceptor(options = {}) {
|
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
// src/interceptors/responseTimeoutInterceptor.ts
|
|
288
|
-
function responseTimeoutInterceptor(options = {}) {
|
|
289
|
-
return {
|
|
290
|
-
onFulfilled: (response) => response,
|
|
291
|
-
onRejected(error) {
|
|
292
|
-
var _a, _b, _c, _d;
|
|
293
|
-
const matcher = createMatcher(options.include, options.exclude);
|
|
294
|
-
if (!matcher((_a = error.config.method) != null ? _a : "", (_b = error.config.url) != null ? _b : "", (_c = error == null ? void 0 : error.response) == null ? void 0 : _c.status)) {
|
|
295
|
-
return Promise.reject(error);
|
|
296
|
-
}
|
|
297
|
-
if (error.code === "ECONNABORTED" && error.message.includes("timeout") || error.code === "ETIMEDOUT") {
|
|
298
|
-
error.code = (_d = options == null ? void 0 : options.normalizeErrorCode) != null ? _d : "TIMEOUT";
|
|
299
|
-
}
|
|
300
|
-
return Promise.reject(error);
|
|
301
|
-
},
|
|
302
|
-
options: options.axiosInterceptorOptions
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
|
|
306
287
|
// src/interceptors/responseRetryInterceptor.ts
|
|
307
288
|
import axios2, { isCancel } from "axios";
|
|
308
289
|
function responseRetryInterceptor(options) {
|
|
@@ -442,6 +423,5 @@ export {
|
|
|
442
423
|
responseBlobInterceptor,
|
|
443
424
|
responseRetryInterceptor,
|
|
444
425
|
responseStatusInterceptor,
|
|
445
|
-
responseTimeoutInterceptor,
|
|
446
426
|
withResponse
|
|
447
427
|
};
|