Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
张婷
forProjectBaseTemp
Commits
96d2bc52
Unverified
Commit
96d2bc52
authored
3 months ago
by
Netfan
Committed by
GitHub
3 months ago
Browse files
Options
Download
Email Patches
Plain Diff
feat: pre-set serialization methods for request parameters (#5814)
添加快捷设置请求参数序列化方法的配置
parent
e91e4e0e
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
206 additions
and
9 deletions
+206
-9
docs/src/guide/essentials/server.md
docs/src/guide/essentials/server.md
+30
-0
packages/effects/request/package.json
packages/effects/request/package.json
+3
-1
packages/effects/request/src/request-client/request-client.ts
...ages/effects/request/src/request-client/request-client.ts
+32
-1
packages/effects/request/src/request-client/types.ts
packages/effects/request/src/request-client/types.ts
+20
-6
playground/src/api/examples/params.ts
playground/src/api/examples/params.ts
+19
-0
playground/src/locales/langs/zh-CN/demos.json
playground/src/locales/langs/zh-CN/demos.json
+2
-1
playground/src/router/routes/modules/demos.ts
playground/src/router/routes/modules/demos.ts
+12
-0
playground/src/views/demos/features/request-params-serializer/index.vue
.../views/demos/features/request-params-serializer/index.vue
+61
-0
pnpm-lock.yaml
pnpm-lock.yaml
+25
-0
pnpm-workspace.yaml
pnpm-workspace.yaml
+2
-0
No files found.
docs/src/guide/essentials/server.md
View file @
96d2bc52
...
...
@@ -110,6 +110,36 @@ VITE_GLOB_API_URL=https://mock-napi.vben.pro/api
项目中默认自带了基于
`axios`
封装的基础的请求配置,核心由
`@vben/request`
包提供。项目没有过多的封装,只是简单的封装了一些常用的配置,如有其他需求,可以自行增加或者调整配置。针对不同的app,可能是用到了不同的组件库以及
`store`
,所以在应用目录下的
`src/api/request.ts`
文件夹下,有对应的请求配置文件,如
`web-antd`
项目下的
`src/api/request.ts`
文件,可以根据自己的需求进行配置。
### 扩展的配置
除了基础的Axios配置外,扩展了部分配置。
```
ts
type
ExtendOptions
<
T
=
any
>
=
{
/**
* 参数序列化方式。预置了几种针对数组的序列化类型
* - brackets: ids[]=1&ids[]=2&ids[]=3
* - comma: ids=1,2,3
* - indices: ids[0]=1&ids[1]=2&ids[2]=3
* - repeat: ids=1&ids=2&ids=3
* @default 'brackets'
*/
paramsSerializer
?:
|
'
brackets
'
|
'
comma
'
|
'
indices
'
|
'
repeat
'
|
AxiosRequestConfig
<
T
>
[
'
paramsSerializer
'
];
/**
* 响应数据的返回方式。
* - raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查。
* - body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)。
* - data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)。
*/
responseReturn
?:
'
body
'
|
'
data
'
|
'
raw
'
;
};
```
### 请求示例
#### GET 请求
...
...
This diff is collapsed.
Click to expand it.
packages/effects/request/package.json
View file @
96d2bc52
...
...
@@ -22,9 +22,11 @@
"dependencies"
:
{
"@vben/locales"
:
"workspace:*"
,
"@vben/utils"
:
"workspace:*"
,
"axios"
:
"catalog:"
"axios"
:
"catalog:"
,
"qs"
:
"catalog:"
},
"devDependencies"
:
{
"@types/qs"
:
"catalog:"
,
"axios-mock-adapter"
:
"catalog:"
}
}
This diff is collapsed.
Click to expand it.
packages/effects/request/src/request-client/request-client.ts
View file @
96d2bc52
...
...
@@ -2,14 +2,39 @@ import type { AxiosInstance, AxiosResponse } from 'axios';
import
type
{
RequestClientConfig
,
RequestClientOptions
}
from
'
./types
'
;
import
{
bindMethods
,
merge
}
from
'
@vben/utils
'
;
import
{
bindMethods
,
isString
,
merge
}
from
'
@vben/utils
'
;
import
axios
from
'
axios
'
;
import
qs
from
'
qs
'
;
import
{
FileDownloader
}
from
'
./modules/downloader
'
;
import
{
InterceptorManager
}
from
'
./modules/interceptor
'
;
import
{
FileUploader
}
from
'
./modules/uploader
'
;
function
getParamsSerializer
(
paramsSerializer
:
RequestClientOptions
[
'
paramsSerializer
'
],
)
{
if
(
isString
(
paramsSerializer
))
{
switch
(
paramsSerializer
)
{
case
'
brackets
'
:
{
return
(
params
:
any
)
=>
qs
.
stringify
(
params
,
{
arrayFormat
:
'
brackets
'
});
}
case
'
comma
'
:
{
return
(
params
:
any
)
=>
qs
.
stringify
(
params
,
{
arrayFormat
:
'
comma
'
});
}
case
'
indices
'
:
{
return
(
params
:
any
)
=>
qs
.
stringify
(
params
,
{
arrayFormat
:
'
indices
'
});
}
case
'
repeat
'
:
{
return
(
params
:
any
)
=>
qs
.
stringify
(
params
,
{
arrayFormat
:
'
repeat
'
});
}
}
}
return
paramsSerializer
;
}
class
RequestClient
{
public
addRequestInterceptor
:
InterceptorManager
[
'
addRequestInterceptor
'
];
...
...
@@ -39,6 +64,9 @@ class RequestClient {
};
const
{
...
axiosConfig
}
=
options
;
const
requestConfig
=
merge
(
axiosConfig
,
defaultConfig
);
requestConfig
.
paramsSerializer
=
getParamsSerializer
(
requestConfig
.
paramsSerializer
,
);
this
.
instance
=
axios
.
create
(
requestConfig
);
bindMethods
(
this
);
...
...
@@ -108,6 +136,9 @@ class RequestClient {
const
response
:
AxiosResponse
<
T
>
=
await
this
.
instance
({
url
,
...
config
,
...(
config
.
paramsSerializer
?
{
paramsSerializer
:
getParamsSerializer
(
config
.
paramsSerializer
)
}
:
{}),
});
return
response
as
T
;
}
catch
(
error
:
any
)
{
...
...
This diff is collapsed.
Click to expand it.
packages/effects/request/src/request-client/types.ts
View file @
96d2bc52
...
...
@@ -5,15 +5,29 @@ import type {
InternalAxiosRequestConfig
,
}
from
'
axios
'
;
type
ExtendOptions
=
{
/** 响应数据的返回方式。
* raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查。
* body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)。
* data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)。
type
ExtendOptions
<
T
=
any
>
=
{
/**
* 参数序列化方式。预置的有
* - brackets: ids[]=1&ids[]=2&ids[]=3
* - comma: ids=1,2,3
* - indices: ids[0]=1&ids[1]=2&ids[2]=3
* - repeat: ids=1&ids=2&ids=3
*/
paramsSerializer
?:
|
'
brackets
'
|
'
comma
'
|
'
indices
'
|
'
repeat
'
|
AxiosRequestConfig
<
T
>
[
'
paramsSerializer
'
];
/**
* 响应数据的返回方式。
* - raw: 原始的AxiosResponse,包括headers、status等,不做是否成功请求的检查。
* - body: 返回响应数据的BODY部分(只会根据status检查请求是否成功,忽略对code的判断,这种情况下应由调用方检查请求是否成功)。
* - data: 解构响应的BODY数据,只返回其中的data节点数据(会检查status和code是否为成功状态)。
*/
responseReturn
?:
'
body
'
|
'
data
'
|
'
raw
'
;
};
type
RequestClientConfig
<
T
=
any
>
=
AxiosRequestConfig
<
T
>
&
ExtendOptions
;
type
RequestClientConfig
<
T
=
any
>
=
AxiosRequestConfig
<
T
>
&
ExtendOptions
<
T
>
;
type
RequestResponse
<
T
=
any
>
=
AxiosResponse
<
T
>
&
{
config
:
RequestClientConfig
<
T
>
;
...
...
This diff is collapsed.
Click to expand it.
playground/src/api/examples/params.ts
0 → 100644
View file @
96d2bc52
import
type
{
Recordable
}
from
'
@vben/types
'
;
import
{
requestClient
}
from
'
#/api/request
'
;
/**
* 发起数组请求
*/
async
function
getParamsData
(
params
:
Recordable
<
any
>
,
type
:
'
brackets
'
|
'
comma
'
|
'
indices
'
|
'
repeat
'
,
)
{
return
requestClient
.
get
(
'
/status
'
,
{
params
,
paramsSerializer
:
type
,
responseReturn
:
'
raw
'
,
});
}
export
{
getParamsData
};
This diff is collapsed.
Click to expand it.
playground/src/locales/langs/zh-CN/demos.json
View file @
96d2bc52
...
...
@@ -50,7 +50,8 @@
"clipboard"
:
"剪贴板"
,
"menuWithQuery"
:
"带参菜单"
,
"openInNewWindow"
:
"新窗口打开"
,
"fileDownload"
:
"文件下载"
"fileDownload"
:
"文件下载"
,
"requestParamsSerializer"
:
"参数序列化"
},
"breadcrumb"
:
{
"navigation"
:
"面包屑导航"
,
...
...
This diff is collapsed.
Click to expand it.
playground/src/router/routes/modules/demos.ts
View file @
96d2bc52
...
...
@@ -243,6 +243,18 @@ const routes: RouteRecordRaw[] = [
title
:
'
Tanstack Query
'
,
},
},
{
name
:
'
RequestParamsSerializerDemo
'
,
path
:
'
/demos/features/request-params-serializer
'
,
component
:
()
=>
import
(
'
#/views/demos/features/request-params-serializer/index.vue
'
),
meta
:
{
icon
:
'
lucide:git-pull-request-arrow
'
,
title
:
$t
(
'
demos.features.requestParamsSerializer
'
),
},
},
],
},
// 面包屑导航
...
...
This diff is collapsed.
Click to expand it.
playground/src/views/demos/features/request-params-serializer/index.vue
0 → 100644
View file @
96d2bc52
<
script
lang=
"ts"
setup
>
import
{
computed
,
ref
,
watchEffect
}
from
'
vue
'
;
import
{
Page
}
from
'
@vben/common-ui
'
;
import
{
Card
,
Radio
,
RadioGroup
}
from
'
ant-design-vue
'
;
import
{
getParamsData
}
from
'
#/api/examples/params
'
;
const
params
=
{
ids
:
[
2512
,
3241
,
4255
]
};
const
paramsSerializer
=
ref
<
'
brackets
'
|
'
comma
'
|
'
indices
'
|
'
repeat
'
>
(
'
brackets
'
,
);
const
response
=
ref
(
''
);
const
paramsStr
=
computed
(()
=>
{
// 写一段代码,从完整的URL中提取参数部分
const
url
=
response
.
value
;
return
new
URL
(
url
).
searchParams
.
toString
();
});
watchEffect
(()
=>
{
getParamsData
(
params
,
paramsSerializer
.
value
).
then
((
res
)
=>
{
response
.
value
=
res
.
request
.
responseURL
;
});
});
</
script
>
<
template
>
<Page
title=
"请求参数序列化"
description=
"不同的后台接口可能对数组类型的GET参数的解析方式不同,我们预置了几种数组序列化方式,通过配置 paramsSerializer 来实现不同的序列化方式"
>
<Card>
<RadioGroup
v-model:value=
"paramsSerializer"
name=
"paramsSerializer"
>
<Radio
value=
"brackets"
>
brackets
</Radio>
<Radio
value=
"comma"
>
comma
</Radio>
<Radio
value=
"indices"
>
indices
</Radio>
<Radio
value=
"repeat"
>
repeat
</Radio>
</RadioGroup>
<div
class=
"mt-4 flex flex-col gap-4"
>
<div>
<h3>
需要提交的参数
</h3>
<div>
{{
JSON
.
stringify
(
params
,
null
,
2
)
}}
</div>
</div>
<template
v-if=
"response"
>
<div>
<h3>
访问地址
</h3>
<pre>
{{
response
}}
</pre>
</div>
<div>
<h3>
参数字符串
</h3>
<pre>
{{
paramsStr
}}
</pre>
</div>
<div>
<h3>
参数解码
</h3>
<pre>
{{
decodeURIComponent
(
paramsStr
)
}}
</pre>
</div>
</
template
>
</div>
</Card>
</Page>
</template>
This diff is collapsed.
Click to expand it.
pnpm-lock.yaml
View file @
96d2bc52
...
...
@@ -111,6 +111,9 @@ catalogs:
'@types/qrcode':
specifier: ^1.5.5
version: 1.5.5
'@types/qs':
specifier: ^6.9.18
version: 6.9.18
'@types/sortablejs':
specifier: ^1.15.8
version: 1.15.8
...
...
@@ -369,6 +372,9 @@ catalogs:
qrcode:
specifier: ^1.5.4
version: 1.5.4
qs:
specifier: ^6.14.0
version: 6.14.0
radix-vue:
specifier: ^1.9.17
version: 1.9.17
...
...
@@ -1714,7 +1720,13 @@ importers:
axios:
specifier: 'catalog:'
version: 1.8.2
qs:
specifier: 'catalog:'
version: 6.14.0
devDependencies:
'@types/qs':
specifier: 'catalog:'
version: 6.9.18
axios-mock-adapter:
specifier: 'catalog:'
version: 2.1.0(axios@1.8.2)
...
...
@@ -4331,6 +4343,9 @@ packages:
'@types/qrcode@1.5.5':
resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==}
'@types/qs@6.9.18':
resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==}
'@types/readdir-glob@1.1.5':
resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==}
...
...
@@ -8650,6 +8665,10 @@ packages:
engines: {node: '>=10.13.0'}
hasBin: true
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
quansync@0.2.8:
resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==}
...
...
@@ -13162,6 +13181,8 @@ snapshots:
dependencies:
'@types/node': 22.13.10
'@types/qs@6.9.18': {}
'@types/readdir-glob@1.1.5':
dependencies:
'@types/node': 22.13.10
...
...
@@ -17951,6 +17972,10 @@ snapshots:
pngjs: 5.0.0
yargs: 15.4.1
qs@6.14.0:
dependencies:
side-channel: 1.1.0
quansync@0.2.8: {}
queue-microtask@1.2.3: {}
...
...
This diff is collapsed.
Click to expand it.
pnpm-workspace.yaml
View file @
96d2bc52
...
...
@@ -50,6 +50,7 @@ catalog:
'
@types/nprogress'
:
^0.2.3
'
@types/postcss-import'
:
^14.0.3
'
@types/qrcode'
:
^1.5.5
'
@types/qs'
:
^6.9.18
'
@types/sortablejs'
:
^1.15.8
'
@typescript-eslint/eslint-plugin'
:
^8.26.0
'
@typescript-eslint/parser'
:
^8.26.0
...
...
@@ -139,6 +140,7 @@ catalog:
prettier-plugin-tailwindcss
:
^0.6.11
publint
:
^0.2.12
qrcode
:
^1.5.4
qs
:
^6.14.0
radix-vue
:
^1.9.17
resolve.exports
:
^2.0.3
rimraf
:
^6.0.1
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment