@varlet/axle 0.0.25 → 0.1.0
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 +265 -17
- package/README.zh-CN.md +315 -0
- package/es/instance.d.ts +5 -5
- package/es/instance.js +14 -7
- package/es/use.d.ts +3 -0
- package/es/use.js +4 -1
- package/es/useAllData.d.ts +1 -0
- package/es/useAllData.js +11 -0
- package/es/useAverageProgress.d.ts +2 -0
- package/es/useAverageProgress.js +9 -0
- package/es/useHasLoading.d.ts +2 -0
- package/es/useHasLoading.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
<span>English</span> |
|
|
2
|
+
<a href="https://github.com/varletjs/axle/blob/main/README.zh-CN.md">中文</a>
|
|
3
|
+
|
|
1
4
|
### Intro
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
Progressive request tool based on axios. It does not destroy the original abilities of axios, and helps you process requests more easily.
|
|
4
7
|
|
|
5
|
-
###
|
|
8
|
+
### QuickStart
|
|
6
9
|
|
|
7
10
|
#### Install
|
|
8
11
|
|
|
@@ -19,22 +22,178 @@ yarn add @varlet/axle
|
|
|
19
22
|
pnpm add @varlet/axle
|
|
20
23
|
```
|
|
21
24
|
|
|
22
|
-
#### Request
|
|
25
|
+
#### Send Request
|
|
26
|
+
|
|
27
|
+
Axle normalizes the parameters of the request function, and expands more request functions for different interface requirements. Here is a simple example.
|
|
23
28
|
|
|
24
29
|
```js
|
|
25
30
|
import { createAxle } from '@varlet/axle'
|
|
26
31
|
|
|
27
|
-
// create axle instance
|
|
28
32
|
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
29
33
|
|
|
34
|
+
axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} })
|
|
35
|
+
axle.post('/url', { name: 'Axle' }, { headers: {} })
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Config
|
|
39
|
+
|
|
40
|
+
Axle fully supports all configuration abilities of axios.
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
30
44
|
// The built-in axios of the axle, the usage is exactly the same as that of axios, and shares the configuration with the axle.
|
|
31
45
|
const { axios } = axle
|
|
32
46
|
|
|
33
|
-
|
|
34
|
-
|
|
47
|
+
axios.defaults.baseURL = 'https://api.example.com'
|
|
48
|
+
axios.defaults.headers.common['TOKEN'] = TOKEN
|
|
49
|
+
axios.defaults.timeout = 2500
|
|
50
|
+
|
|
51
|
+
// Add a request interceptor
|
|
52
|
+
axios.interceptors.request.use((config) => {
|
|
53
|
+
// Do something before request is sent
|
|
54
|
+
return config
|
|
55
|
+
}, (error) => {
|
|
56
|
+
// Do something with request error
|
|
57
|
+
return Promise.reject(error)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Add a response interceptor
|
|
61
|
+
axios.interceptors.response.use((response) => {
|
|
62
|
+
// Any status code that lie within the range of 2xx cause this function to trigger
|
|
63
|
+
// Do something with response data
|
|
64
|
+
return response
|
|
65
|
+
}, (error) => {
|
|
66
|
+
// Any status codes that falls outside the range of 2xx cause this function to trigger
|
|
67
|
+
// Do something with response error
|
|
68
|
+
return Promise.reject(error)
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Axle & Axios Request Functions
|
|
73
|
+
|
|
74
|
+
The request function provided by Axle can help you send requests more easily. Here are some examples including comparison with axios.
|
|
75
|
+
Tips: Take `get` and `post` as examples below, Axle also supports `options`, `head`, `delete`, `patch` , `put` methods.
|
|
76
|
+
|
|
77
|
+
### get
|
|
78
|
+
|
|
79
|
+
#### JSON
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
// axios
|
|
83
|
+
axios.get('/url', { params: { id: 1 } })
|
|
84
|
+
// axle
|
|
85
|
+
axle.get('/url', { id: 1 })
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Blob
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
// axios
|
|
92
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'blob' })
|
|
93
|
+
// axle
|
|
94
|
+
axle.getBlob('/url', { id: 1 })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Text
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
// axios
|
|
101
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'text' })
|
|
102
|
+
// axle
|
|
103
|
+
axle.getText('/url', { id: 1 })
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Document
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
// axios
|
|
110
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'document' })
|
|
111
|
+
// axle
|
|
112
|
+
axle.getDocument('/url', { id: 1 })
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### ArrayBuffer
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
// axios
|
|
119
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' })
|
|
120
|
+
// axle
|
|
121
|
+
axle.getArrayBuffer('/url', { id: 1 })
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Stream
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
// axios
|
|
128
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'stream' })
|
|
129
|
+
// axle
|
|
130
|
+
axle.getStream('/url', { id: 1 })
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## post
|
|
134
|
+
|
|
135
|
+
#### JSON
|
|
136
|
+
|
|
137
|
+
Same with axios.
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
// axios
|
|
141
|
+
axios.post('/url', { name: 'foo' })
|
|
142
|
+
// axle
|
|
143
|
+
axle.post('/url', { name: 'foo' })
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### application/x-www-form-urlencoded
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
// axios
|
|
150
|
+
axios.post('/url', qs.stringify({ name: 'foo' }), {
|
|
151
|
+
headers: {
|
|
152
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
// axle
|
|
156
|
+
axle.postUrlEncode('/url', { name: 'foo' })
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### multipart/form-data
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
// axios
|
|
163
|
+
const formData = new FormData()
|
|
164
|
+
formData.append('name', 'foo')
|
|
165
|
+
formData.append('file', new File())
|
|
166
|
+
|
|
167
|
+
axios.post('/url', formData, {
|
|
168
|
+
headers: {
|
|
169
|
+
'Content-Type': 'multipart/form-data'
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
// axle
|
|
173
|
+
axle.postMultipart('/url', { name: 'foo', file: new File() })
|
|
35
174
|
```
|
|
36
175
|
|
|
37
|
-
|
|
176
|
+
## Utils
|
|
177
|
+
|
|
178
|
+
#### Notify the browser to download the file
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
import { download } from '@varlet/axle'
|
|
182
|
+
|
|
183
|
+
download(await axle.getBlob('/url', { id: 1 }), 'filename')
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Common Header Operate
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
const headers = axle.getHeaders()
|
|
190
|
+
axle.setHeader('TOKEN', TOKEN)
|
|
191
|
+
axle.removeHeader('TOKEN')
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Vue Composition API
|
|
195
|
+
|
|
196
|
+
Axle provides the usage of Vue Composition API style, which encapsulates the `loading status`, `error status`, `upload and download progress` of the request, `return data`, `error retry`, `lifecycle`, etc., And inherit all the configuration of `axios`.
|
|
38
197
|
|
|
39
198
|
```html
|
|
40
199
|
<script setup>
|
|
@@ -42,26 +201,115 @@ import { createAxle } from '@varlet/axle'
|
|
|
42
201
|
import { createUseAxle } from '@varlet/axle/use'
|
|
43
202
|
|
|
44
203
|
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
45
|
-
const useAxle = createUseAxle(
|
|
204
|
+
const useAxle = createUseAxle()
|
|
46
205
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
206
|
+
const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort }] = useAxle({
|
|
207
|
+
// Request initial data
|
|
208
|
+
data: [],
|
|
209
|
+
// Request runner
|
|
50
210
|
runner: axle.get,
|
|
211
|
+
// Request url
|
|
51
212
|
url: '/user',
|
|
213
|
+
// Whether to send the request immediately, defaults false
|
|
214
|
+
immediate: true,
|
|
215
|
+
// The number of retries after a failed request, defaults 0
|
|
216
|
+
retry: 3,
|
|
217
|
+
// Request params, defaults {}
|
|
52
218
|
params: { current: 1, pageSize: 10 },
|
|
53
|
-
|
|
219
|
+
// Axios config, see https://axios-http.com
|
|
220
|
+
config: { headers: {} },
|
|
221
|
+
// lifecycle
|
|
222
|
+
onBefore(refs) {
|
|
223
|
+
const { data, loading, error, uploadProgress, downloadProgress } = refs
|
|
224
|
+
console.log(
|
|
225
|
+
data.value,
|
|
226
|
+
loading.value,
|
|
227
|
+
error.value,
|
|
228
|
+
uploadProgress.value,
|
|
229
|
+
downloadProgress.value
|
|
230
|
+
)
|
|
231
|
+
// Do request before
|
|
232
|
+
},
|
|
233
|
+
onTransform(response, refs) {
|
|
234
|
+
// Handle data transform, The transformed data will be the value of users.
|
|
235
|
+
return response.data
|
|
236
|
+
},
|
|
237
|
+
onSuccess(response, refs) {
|
|
238
|
+
// Do request success
|
|
239
|
+
},
|
|
240
|
+
onError(error, refs) {
|
|
241
|
+
// Do request error
|
|
242
|
+
},
|
|
243
|
+
onAfter(refs) {
|
|
244
|
+
// Do request after
|
|
245
|
+
}
|
|
54
246
|
})
|
|
55
247
|
</script>
|
|
56
248
|
|
|
57
249
|
<template>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
250
|
+
<span>{{ users }}</span>
|
|
251
|
+
<span>{{ loading }}</span>
|
|
252
|
+
<span>{{ error }}</span>
|
|
253
|
+
<span>{{ uploadProgress }}</span>
|
|
254
|
+
<span>{{ downloadProgress }}</span>
|
|
255
|
+
<button @click="getUsers">Send Request</button>
|
|
256
|
+
<button @click="abort">Abort Request</button>
|
|
61
257
|
</template>
|
|
62
258
|
```
|
|
63
259
|
|
|
64
|
-
###
|
|
260
|
+
### Parallel Utils
|
|
261
|
+
|
|
262
|
+
Axle provides some parallel request processing tools, please refer to the following examples.
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<script setup>
|
|
266
|
+
import { createAxle } from '@varlet/axle'
|
|
267
|
+
import { createUseAxle, useAllData, useAverageProgress, useHasLoading } from '@varlet/axle/use'
|
|
268
|
+
|
|
269
|
+
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
270
|
+
const useAxle = createUseAxle()
|
|
271
|
+
|
|
272
|
+
const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({
|
|
273
|
+
data: [],
|
|
274
|
+
runner: axle.get,
|
|
275
|
+
url: '/user',
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({
|
|
279
|
+
data: [],
|
|
280
|
+
runner: axle.get,
|
|
281
|
+
url: '/role',
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
// At the end of all requests, loading is false
|
|
285
|
+
const loading = useHasLoading(isUsersLoading, isRolesLoading)
|
|
286
|
+
// At the end of all requests, downloadProgress is 1
|
|
287
|
+
const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress)
|
|
288
|
+
// Ref<[
|
|
289
|
+
// [{ name: 'foo' }, { name: 'bar' }],
|
|
290
|
+
// [{ role: 'admin' }, { role: 'user' }]
|
|
291
|
+
// ]> <-
|
|
292
|
+
// [
|
|
293
|
+
// Ref<[{ name: 'foo' }, { name: 'bar' }]>,
|
|
294
|
+
// Ref<[{ role: 'admin' }, { role: 'user' }]>
|
|
295
|
+
// ]
|
|
296
|
+
const usersRoles = useAllData(users, roles)
|
|
297
|
+
|
|
298
|
+
function sendAllRequest() {
|
|
299
|
+
// parallel
|
|
300
|
+
getUsers()
|
|
301
|
+
getRoles()
|
|
302
|
+
}
|
|
303
|
+
</script>
|
|
304
|
+
|
|
305
|
+
<template>
|
|
306
|
+
<span>{{ usersRoles }}</span>
|
|
307
|
+
<span>{{ loading }}</span>
|
|
308
|
+
<span>{{ downloadProgress }}</span>
|
|
309
|
+
<button @click="sendAllRequest">Send All Request</button>
|
|
310
|
+
</template>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
|
|
65
314
|
|
|
66
|
-
WIP and Trying
|
|
67
315
|
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
<a href="https://github.com/varletjs/axle/blob/main/README.md">English</a> |
|
|
2
|
+
<span>中文</span>
|
|
3
|
+
|
|
4
|
+
### 介绍
|
|
5
|
+
|
|
6
|
+
基于 [axios](https://axios-http.com/) 的渐进式请求工具。 它不会破坏 `axios` 原有的能力,帮助您更轻松地处理请求。
|
|
7
|
+
|
|
8
|
+
### 快速开始
|
|
9
|
+
|
|
10
|
+
#### 安装
|
|
11
|
+
|
|
12
|
+
```shell
|
|
13
|
+
# 通过 npm, yarn, pnpm 安装
|
|
14
|
+
|
|
15
|
+
# npm
|
|
16
|
+
npm i @varlet/axle -S
|
|
17
|
+
|
|
18
|
+
#yarn
|
|
19
|
+
yarn add @varlet/axle
|
|
20
|
+
|
|
21
|
+
#pnpm
|
|
22
|
+
pnpm add @varlet/axle
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### 发送请求
|
|
26
|
+
|
|
27
|
+
`Axle` 归一化了请求函数的参数,并针对不同的业务需求,扩展了更多请求函数,下面是一个简单的例子。
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { createAxle } from '@varlet/axle'
|
|
31
|
+
|
|
32
|
+
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
33
|
+
|
|
34
|
+
axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} })
|
|
35
|
+
axle.post('/url', { name: 'Axle' }, { headers: {} })
|
|
36
|
+
```
|
|
37
|
+
|
|
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((config) => {
|
|
53
|
+
// 请求前处理
|
|
54
|
+
return config
|
|
55
|
+
}, (error) => {
|
|
56
|
+
// 请求错误处理
|
|
57
|
+
return Promise.reject(error)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// 添加请求后返回拦截器
|
|
61
|
+
axios.interceptors.response.use((response) => {
|
|
62
|
+
// 任何位于 2xx 范围内的状态码都会导致该函数触发
|
|
63
|
+
// 对响应数据做一些事情
|
|
64
|
+
return response
|
|
65
|
+
}, (error) => {
|
|
66
|
+
// 任何超出 2xx 范围的状态代码都会导致此函数触发
|
|
67
|
+
// 对响应错误做一些事情
|
|
68
|
+
return Promise.reject(error)
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Axle & Axios 请求函数
|
|
73
|
+
|
|
74
|
+
`Axle` 提供的请求函数可以帮助您更轻松地发送请求。 以下是一些示例,包括与 `axios` 的比较。
|
|
75
|
+
提示:下面只是以 `get` 和 `post` 为例,除此之外 Axle 还支持 `options`、`head`、`delete`、`patch` 、`put` 方法。
|
|
76
|
+
|
|
77
|
+
### get
|
|
78
|
+
|
|
79
|
+
#### JSON
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
// axios
|
|
83
|
+
axios.get('/url', { params: { id: 1 } })
|
|
84
|
+
// axle
|
|
85
|
+
axle.get('/url', { id: 1 })
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Blob
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
// axios
|
|
92
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'blob' })
|
|
93
|
+
// axle
|
|
94
|
+
axle.getBlob('/url', { id: 1 })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Text
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
// axios
|
|
101
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'text' })
|
|
102
|
+
// axle
|
|
103
|
+
axle.getText('/url', { id: 1 })
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Document
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
// axios
|
|
110
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'document' })
|
|
111
|
+
// axle
|
|
112
|
+
axle.getDocument('/url', { id: 1 })
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### ArrayBuffer
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
// axios
|
|
119
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' })
|
|
120
|
+
// axle
|
|
121
|
+
axle.getArrayBuffer('/url', { id: 1 })
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Stream
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
// axios
|
|
128
|
+
axios.get('/url', { params: { id: 1 }, responseType: 'stream' })
|
|
129
|
+
// axle
|
|
130
|
+
axle.getStream('/url', { id: 1 })
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## post
|
|
134
|
+
|
|
135
|
+
#### JSON
|
|
136
|
+
|
|
137
|
+
和 axios 一致。
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
// axios
|
|
141
|
+
axios.post('/url', { name: 'foo' })
|
|
142
|
+
// axle
|
|
143
|
+
axle.post('/url', { name: 'foo' })
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### application/x-www-form-urlencoded
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
// axios
|
|
150
|
+
axios.post('/url', qs.stringify({ name: 'foo' }), {
|
|
151
|
+
headers: {
|
|
152
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
// axle
|
|
156
|
+
axle.postUrlEncode('/url', { name: 'foo' })
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### multipart/form-data
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
// axios
|
|
163
|
+
const formData = new FormData()
|
|
164
|
+
formData.append('name', 'foo')
|
|
165
|
+
formData.append('file', new File())
|
|
166
|
+
|
|
167
|
+
axios.post('/url', formData, {
|
|
168
|
+
headers: {
|
|
169
|
+
'Content-Type': 'multipart/form-data'
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
// axle
|
|
173
|
+
axle.postMultipart('/url', { name: 'foo', file: new File() })
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 实用工具
|
|
177
|
+
|
|
178
|
+
#### 通知浏览器下载文件
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
import { download } from '@varlet/axle'
|
|
182
|
+
|
|
183
|
+
download(await axle.getBlob('/url', { id: 1 }), 'filename')
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### 公共 header 操作
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
const headers = axle.getHeaders()
|
|
190
|
+
axle.setHeader('TOKEN', TOKEN)
|
|
191
|
+
axle.removeHeader('TOKEN')
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Vue 组合式 API
|
|
195
|
+
|
|
196
|
+
Axle 提供了 Vue Composition API 风格的用法,封装了请求的 `加载状态`, `错误状态`, `请求的上下行进度`,`返回数据`,`错误重试`,`生命周期` 等等,并继承了 `axios` 的所有配置。
|
|
197
|
+
|
|
198
|
+
```html
|
|
199
|
+
<script setup>
|
|
200
|
+
import { createAxle } from '@varlet/axle'
|
|
201
|
+
import { createUseAxle } from '@varlet/axle/use'
|
|
202
|
+
|
|
203
|
+
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
204
|
+
const useAxle = createUseAxle()
|
|
205
|
+
|
|
206
|
+
const [users, getUsers, { loading, error, uploadProgress, downloadProgress, abort }] = useAxle({
|
|
207
|
+
// 请求初始化数据
|
|
208
|
+
data: [],
|
|
209
|
+
// 请求函数
|
|
210
|
+
runner: axle.get,
|
|
211
|
+
// 请求地址
|
|
212
|
+
url: '/user',
|
|
213
|
+
// 是否立即发送请求, 默认值: false
|
|
214
|
+
immediate: true,
|
|
215
|
+
// 错误重试次数, 默认值: 0
|
|
216
|
+
retry: 3,
|
|
217
|
+
// 请求参数, 默认值: {}
|
|
218
|
+
params: { current: 1, pageSize: 10 },
|
|
219
|
+
// Axios 配置, see https://axios-http.com
|
|
220
|
+
config: { headers: {} },
|
|
221
|
+
// 生命周期
|
|
222
|
+
onBefore(refs) {
|
|
223
|
+
const { data, loading, error, uploadProgress, downloadProgress } = refs
|
|
224
|
+
console.log(
|
|
225
|
+
data.value,
|
|
226
|
+
loading.value,
|
|
227
|
+
error.value,
|
|
228
|
+
uploadProgress.value,
|
|
229
|
+
downloadProgress.value
|
|
230
|
+
)
|
|
231
|
+
// 处理请求前逻辑
|
|
232
|
+
},
|
|
233
|
+
onTransform(response, refs) {
|
|
234
|
+
// 处理数据转换,转换后的数据将成为 users 的值。
|
|
235
|
+
return response.data
|
|
236
|
+
},
|
|
237
|
+
onSuccess(response, refs) {
|
|
238
|
+
// 处理请求成功逻辑
|
|
239
|
+
},
|
|
240
|
+
onError(error, refs) {
|
|
241
|
+
// 处理请求错误逻辑
|
|
242
|
+
},
|
|
243
|
+
onAfter(refs) {
|
|
244
|
+
// 处理请求结束逻辑,无论成功失败都会触发。
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
</script>
|
|
248
|
+
|
|
249
|
+
<template>
|
|
250
|
+
<span>{{ users }}</span>
|
|
251
|
+
<span>{{ loading }}</span>
|
|
252
|
+
<span>{{ error }}</span>
|
|
253
|
+
<span>{{ uploadProgress }}</span>
|
|
254
|
+
<span>{{ downloadProgress }}</span>
|
|
255
|
+
<button @click="getUsers">发送请求</button>
|
|
256
|
+
<button @click="abort">中断请求</button>
|
|
257
|
+
</template>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### 并行请求实用工具
|
|
261
|
+
|
|
262
|
+
Axle 提供了一些并行请求处理工具,请参考以下示例。
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<script setup>
|
|
266
|
+
import { createAxle } from '@varlet/axle'
|
|
267
|
+
import { createUseAxle, useAllData, useAverageProgress, useHasLoading } from '@varlet/axle/use'
|
|
268
|
+
|
|
269
|
+
const axle = createAxle(/** @see https://axios-http.com **/)
|
|
270
|
+
const useAxle = createUseAxle()
|
|
271
|
+
|
|
272
|
+
const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({
|
|
273
|
+
data: [],
|
|
274
|
+
runner: axle.get,
|
|
275
|
+
url: '/user',
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({
|
|
279
|
+
data: [],
|
|
280
|
+
runner: axle.get,
|
|
281
|
+
url: '/role',
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
// 所有请求结束时,loading 为 false
|
|
285
|
+
const loading = useHasLoading(isUsersLoading, isRolesLoading)
|
|
286
|
+
// 所有请求结束时,downloadProgress 为 1
|
|
287
|
+
const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress)
|
|
288
|
+
// Ref<[
|
|
289
|
+
// [{ name: 'foo' }, { name: 'bar' }],
|
|
290
|
+
// [{ role: 'admin' }, { role: 'user' }]
|
|
291
|
+
// ]> <-
|
|
292
|
+
// [
|
|
293
|
+
// Ref<[{ name: 'foo' }, { name: 'bar' }]>,
|
|
294
|
+
// Ref<[{ role: 'admin' }, { role: 'user' }]>
|
|
295
|
+
// ]
|
|
296
|
+
const usersRoles = useAllData(users, roles)
|
|
297
|
+
|
|
298
|
+
function sendAllRequest() {
|
|
299
|
+
// parallel
|
|
300
|
+
getUsers()
|
|
301
|
+
getRoles()
|
|
302
|
+
}
|
|
303
|
+
</script>
|
|
304
|
+
|
|
305
|
+
<template>
|
|
306
|
+
<span>{{ usersRoles }}</span>
|
|
307
|
+
<span>{{ loading }}</span>
|
|
308
|
+
<span>{{ downloadProgress }}</span>
|
|
309
|
+
<button @click="sendAllRequest">发送全部请求</button>
|
|
310
|
+
</template>
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
package/es/instance.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, ResponseType } from 'axios';
|
|
1
|
+
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, HeadersDefaults, ResponseType } from 'axios';
|
|
2
2
|
export type AxleRequestConfig = AxiosRequestConfig & {
|
|
3
3
|
exceptionMessage?: any;
|
|
4
4
|
};
|
|
@@ -32,15 +32,15 @@ export type AxleInstance = {
|
|
|
32
32
|
deleteArrayBuffer: FetchHelper;
|
|
33
33
|
deleteStream: FetchHelper;
|
|
34
34
|
post: ModifyHelper;
|
|
35
|
-
|
|
35
|
+
postUrlEncode: ModifyHelper;
|
|
36
36
|
postMultipart: ModifyHelper;
|
|
37
37
|
put: ModifyHelper;
|
|
38
|
-
|
|
38
|
+
putUrlEncode: ModifyHelper;
|
|
39
39
|
putMultipart: ModifyHelper;
|
|
40
40
|
patch: ModifyHelper;
|
|
41
|
-
|
|
41
|
+
patchUrlEncode: ModifyHelper;
|
|
42
42
|
patchMultipart: ModifyHelper;
|
|
43
|
-
|
|
43
|
+
getHeaders(): HeadersDefaults['common'];
|
|
44
44
|
setHeader(key: string, value: string): void;
|
|
45
45
|
removeHeader(key: string | string[]): void;
|
|
46
46
|
axios: AxiosInstance;
|
package/es/instance.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import qs from 'qs';
|
|
3
|
+
import { inBrowser } from '@varlet/shared';
|
|
3
4
|
export function createFetchHelper(service, method, responseType) {
|
|
4
5
|
return function (url, params, config) {
|
|
5
6
|
return service[method](url, Object.assign({ params,
|
|
@@ -22,6 +23,9 @@ export function createModifyHelper(service, method, contentType) {
|
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
export function download(url, filename) {
|
|
26
|
+
if (!inBrowser()) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
25
29
|
const a = document.createElement('a');
|
|
26
30
|
a.download = filename;
|
|
27
31
|
a.style.display = 'none';
|
|
@@ -33,6 +37,9 @@ export function download(url, filename) {
|
|
|
33
37
|
}
|
|
34
38
|
export function createAxle(config = {}) {
|
|
35
39
|
const service = axios.create(config);
|
|
40
|
+
function getHeaders() {
|
|
41
|
+
return service.defaults.headers['common'];
|
|
42
|
+
}
|
|
36
43
|
function setHeader(key, value) {
|
|
37
44
|
;
|
|
38
45
|
service.defaults.headers['common'][key] = value;
|
|
@@ -69,16 +76,16 @@ export function createAxle(config = {}) {
|
|
|
69
76
|
deleteArrayBuffer: createFetchHelper(service, 'delete', 'arraybuffer'),
|
|
70
77
|
deleteText: createFetchHelper(service, 'delete', 'text'),
|
|
71
78
|
deleteStream: createFetchHelper(service, 'delete', 'stream'),
|
|
72
|
-
post: createModifyHelper(service, 'post', 'application/
|
|
73
|
-
|
|
79
|
+
post: createModifyHelper(service, 'post', 'application/json'),
|
|
80
|
+
postUrlEncode: createModifyHelper(service, 'post', 'application/x-www-form-urlencoded'),
|
|
74
81
|
postMultipart: createModifyHelper(service, 'post', 'multipart/form-data'),
|
|
75
|
-
put: createModifyHelper(service, 'put', 'application/
|
|
76
|
-
|
|
82
|
+
put: createModifyHelper(service, 'put', 'application/json'),
|
|
83
|
+
putUrlEncode: createModifyHelper(service, 'put', 'application/x-www-form-urlencoded'),
|
|
77
84
|
putMultipart: createModifyHelper(service, 'put', 'multipart/form-data'),
|
|
78
|
-
patch: createModifyHelper(service, 'patch', 'application/
|
|
79
|
-
|
|
85
|
+
patch: createModifyHelper(service, 'patch', 'application/json'),
|
|
86
|
+
patchUrlEncode: createModifyHelper(service, 'patch', 'application/x-www-form-urlencoded'),
|
|
80
87
|
patchMultipart: createModifyHelper(service, 'patch', 'multipart/form-data'),
|
|
81
|
-
|
|
88
|
+
getHeaders,
|
|
82
89
|
setHeader,
|
|
83
90
|
removeHeader,
|
|
84
91
|
axios: service,
|
package/es/use.d.ts
CHANGED
|
@@ -43,3 +43,6 @@ export interface CreateUseAxleOptions {
|
|
|
43
43
|
onTransform?(response: any, refs: any): any;
|
|
44
44
|
}
|
|
45
45
|
export declare function createUseAxle(options?: CreateUseAxleOptions): <D = any, R = any, P = Record<string, any>>(options: UseAxleOptions<D, R, P>) => UseAxleInstance<D, R, P>;
|
|
46
|
+
export * from './useAllData.js';
|
|
47
|
+
export * from './useHasLoading.js';
|
|
48
|
+
export * from './useAverageProgress.js';
|
package/es/use.js
CHANGED
|
@@ -16,7 +16,7 @@ export function createUseAxle(options = {}) {
|
|
|
16
16
|
loading,
|
|
17
17
|
error,
|
|
18
18
|
downloadProgress,
|
|
19
|
-
uploadProgress
|
|
19
|
+
uploadProgress,
|
|
20
20
|
};
|
|
21
21
|
let controller = new AbortController();
|
|
22
22
|
const run = async (options = {}) => {
|
|
@@ -81,3 +81,6 @@ export function createUseAxle(options = {}) {
|
|
|
81
81
|
};
|
|
82
82
|
return useAxle;
|
|
83
83
|
}
|
|
84
|
+
export * from './useAllData.js';
|
|
85
|
+
export * from './useHasLoading.js';
|
|
86
|
+
export * from './useAverageProgress.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useAllData<DC extends any[]>(...dataCollection: DC): import("vue").WritableComputedRef<any[]>;
|
package/es/useAllData.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
export function useAllData(...dataCollection) {
|
|
3
|
+
return computed({
|
|
4
|
+
get: () => dataCollection.map((data) => data.value),
|
|
5
|
+
set(values) {
|
|
6
|
+
dataCollection.forEach((data, index) => {
|
|
7
|
+
data.value = values[index];
|
|
8
|
+
});
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ref, watch } from "vue";
|
|
2
|
+
export function useAverageProgress(...progressCollection) {
|
|
3
|
+
const averageProgress = ref(0);
|
|
4
|
+
watch(() => progressCollection.map(progress => progress.value), (newProgressCollection) => {
|
|
5
|
+
const total = newProgressCollection.reduce((total, progress) => total + progress, 0);
|
|
6
|
+
averageProgress.value = total / progressCollection.length;
|
|
7
|
+
}, { immediate: true });
|
|
8
|
+
return averageProgress;
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ref, watch } from "vue";
|
|
2
|
+
export function useHasLoading(...loadings) {
|
|
3
|
+
const hasLoading = ref(false);
|
|
4
|
+
watch(() => loadings.map(loading => loading.value), (newLoadings) => {
|
|
5
|
+
hasLoading.value = newLoadings.some(Boolean);
|
|
6
|
+
}, { immediate: true });
|
|
7
|
+
return hasLoading;
|
|
8
|
+
}
|