uview-pro 0.0.18 → 0.0.20
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/changelog.md +175 -133
- package/index.ts +5 -12
- package/libs/function/toast.ts +4 -4
- package/libs/request/index.ts +124 -138
- package/package.json +1 -1
- package/readme.md +20 -20
- package/libs/request/uni-http.md +0 -156
- package/libs/request/uni-http.ts +0 -434
package/libs/request/index.ts
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
import deepMerge from '../function/deepMerge';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 请求配置项Meta类型定义
|
|
5
|
+
*/
|
|
6
|
+
export interface RequestMeta {
|
|
7
|
+
toast?: boolean;
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
originalData?: boolean;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
14
|
* 请求配置项类型定义
|
|
6
15
|
*/
|
|
7
16
|
export interface RequestConfig {
|
|
8
|
-
baseUrl
|
|
9
|
-
header
|
|
10
|
-
method
|
|
11
|
-
dataType
|
|
12
|
-
responseType
|
|
13
|
-
|
|
14
|
-
loadingText: string;
|
|
15
|
-
loadingTime: number;
|
|
16
|
-
timer: ReturnType<typeof setTimeout> | null;
|
|
17
|
-
originalData: boolean;
|
|
18
|
-
loadingMask: boolean;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
header?: Record<string, any>;
|
|
19
|
+
method?: string;
|
|
20
|
+
dataType?: string;
|
|
21
|
+
responseType?: string;
|
|
22
|
+
meta?: RequestMeta;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
@@ -29,7 +33,7 @@ export interface RequestInterceptor {
|
|
|
29
33
|
/**
|
|
30
34
|
* 请求参数类型定义
|
|
31
35
|
*/
|
|
32
|
-
interface RequestOptions {
|
|
36
|
+
export interface RequestOptions {
|
|
33
37
|
url: string;
|
|
34
38
|
header?: Record<string, any>;
|
|
35
39
|
method?: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
|
|
@@ -38,14 +42,32 @@ interface RequestOptions {
|
|
|
38
42
|
responseType?: string;
|
|
39
43
|
params?: Record<string, any>;
|
|
40
44
|
complete?: (response: any) => void;
|
|
45
|
+
meta?: RequestMeta;
|
|
41
46
|
}
|
|
42
|
-
export type { RequestOptions };
|
|
43
47
|
|
|
44
|
-
class Request {
|
|
45
|
-
config: RequestConfig;
|
|
46
|
-
interceptor: RequestInterceptor;
|
|
47
|
-
options?: RequestOptions;
|
|
48
|
+
export class Request {
|
|
49
|
+
public config: RequestConfig;
|
|
50
|
+
public interceptor: RequestInterceptor;
|
|
51
|
+
public options?: RequestOptions;
|
|
48
52
|
|
|
53
|
+
constructor() {
|
|
54
|
+
this.config = {
|
|
55
|
+
baseUrl: '', // 请求的根域名
|
|
56
|
+
header: {}, // 默认的请求头
|
|
57
|
+
method: 'POST', // 请求方式
|
|
58
|
+
dataType: 'json', // 设置为json,返回后uni.request会对数据进行一次JSON.parse
|
|
59
|
+
responseType: 'text', // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
|
|
60
|
+
meta: {
|
|
61
|
+
originalData: true, // 是否在拦截器中返回服务端的原始数据,见文档说明
|
|
62
|
+
toast: false, // 是否在请求出错时,弹出toast
|
|
63
|
+
loading: false // 是否显示加载中
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
this.interceptor = {
|
|
67
|
+
request: null,
|
|
68
|
+
response: null
|
|
69
|
+
};
|
|
70
|
+
}
|
|
49
71
|
/**
|
|
50
72
|
* 设置全局默认配置
|
|
51
73
|
* @param customConfig 自定义配置
|
|
@@ -58,10 +80,17 @@ class Request {
|
|
|
58
80
|
* 主要请求部分
|
|
59
81
|
* @param options 请求参数
|
|
60
82
|
*/
|
|
61
|
-
request(options: RequestOptions): Promise<
|
|
62
|
-
//
|
|
83
|
+
request<T = unknown>(options: RequestOptions): Promise<T> {
|
|
84
|
+
// 合并 meta 配置,优先级:单次请求 > 全局
|
|
85
|
+
const mergedMeta: RequestMeta = {
|
|
86
|
+
...this.config.meta,
|
|
87
|
+
...(options.meta || {})
|
|
88
|
+
};
|
|
89
|
+
// 让 options.meta 传递到拦截器
|
|
90
|
+
options.meta = mergedMeta;
|
|
91
|
+
|
|
63
92
|
if (this.interceptor.request && typeof this.interceptor.request === 'function') {
|
|
64
|
-
|
|
93
|
+
const interceptorRequest = this.interceptor.request(options);
|
|
65
94
|
if (interceptorRequest === false) {
|
|
66
95
|
// 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
|
|
67
96
|
return new Promise(() => {});
|
|
@@ -77,19 +106,18 @@ class Request {
|
|
|
77
106
|
// 保证 url 一定为 string
|
|
78
107
|
if (!options.url) options.url = '';
|
|
79
108
|
|
|
80
|
-
return new Promise<
|
|
109
|
+
return new Promise<T>((resolve, reject) => {
|
|
81
110
|
options.complete = (response: any) => {
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (this.config.originalData) {
|
|
111
|
+
// 读取 meta 配置
|
|
112
|
+
const meta = options.meta || this.config.meta || {};
|
|
113
|
+
const originalData = meta.originalData ?? false;
|
|
114
|
+
// 拦截器处理,加入request的配置参数
|
|
115
|
+
response.config = options;
|
|
116
|
+
if (originalData) {
|
|
89
117
|
// 判断是否存在拦截器
|
|
90
118
|
if (this.interceptor.response && typeof this.interceptor.response === 'function') {
|
|
91
|
-
|
|
92
|
-
// 如果拦截器不返回false
|
|
119
|
+
const resInterceptors = this.interceptor.response(response);
|
|
120
|
+
// 如果拦截器不返回false,就将拦截器返回的内容给请求的then回调
|
|
93
121
|
if (resInterceptors !== false) {
|
|
94
122
|
resolve(resInterceptors);
|
|
95
123
|
} else {
|
|
@@ -97,13 +125,13 @@ class Request {
|
|
|
97
125
|
reject(response);
|
|
98
126
|
}
|
|
99
127
|
} else {
|
|
100
|
-
//
|
|
128
|
+
// 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
|
|
101
129
|
resolve(response);
|
|
102
130
|
}
|
|
103
131
|
} else {
|
|
104
|
-
if (response.statusCode
|
|
132
|
+
if (response.statusCode === 200) {
|
|
105
133
|
if (this.interceptor.response && typeof this.interceptor.response === 'function') {
|
|
106
|
-
|
|
134
|
+
const resInterceptors = this.interceptor.response(response.data);
|
|
107
135
|
if (resInterceptors !== false) {
|
|
108
136
|
resolve(resInterceptors);
|
|
109
137
|
} else {
|
|
@@ -114,124 +142,82 @@ class Request {
|
|
|
114
142
|
resolve(response.data);
|
|
115
143
|
}
|
|
116
144
|
} else {
|
|
117
|
-
// 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
|
|
118
|
-
// if(response.errMsg) {
|
|
119
|
-
// uni.showModal({
|
|
120
|
-
// title: response.errMsg
|
|
121
|
-
// });
|
|
122
|
-
// }
|
|
123
145
|
reject(response);
|
|
124
146
|
}
|
|
125
147
|
}
|
|
126
148
|
};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
options.url = validate.url(options.url) ? options.url : this.config.baseUrl + (options.url.indexOf('/') == 0 ? options.url : '/' + options.url);
|
|
130
|
-
|
|
131
|
-
// 是否显示loading
|
|
132
|
-
// 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
|
|
133
|
-
// 而没有清除前者的定时器,导致前者超时,一直显示loading
|
|
134
|
-
if (this.config.showLoading && !this.config.timer) {
|
|
135
|
-
this.config.timer = setTimeout(() => {
|
|
136
|
-
uni.showLoading({
|
|
137
|
-
title: this.config.loadingText,
|
|
138
|
-
mask: this.config.loadingMask
|
|
139
|
-
});
|
|
140
|
-
this.config.timer = null;
|
|
141
|
-
}, this.config.loadingTime);
|
|
142
|
-
}
|
|
149
|
+
// 判断用户传递的URL是否http开头
|
|
150
|
+
options.url = options.url && options.url.indexOf('http') !== 0 ? this.config.baseUrl + (options.url.indexOf('/') === 0 ? options.url : `/${options.url}`) : options.url;
|
|
143
151
|
uni.request(options);
|
|
144
152
|
});
|
|
145
|
-
// .catch(res => {
|
|
146
|
-
// // 如果返回reject(),不让其进入this.$u.post().then().catch()后面的catct()
|
|
147
|
-
// // 因为很多人都会忘了写后面的catch(),导致报错捕获不到catch
|
|
148
|
-
// return new Promise(()=>{});
|
|
149
|
-
// })
|
|
150
153
|
}
|
|
151
154
|
|
|
152
|
-
|
|
153
|
-
this.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
get<T = unknown>(url: string, data: any = {}, options: { header?: Record<string, any>; meta?: RequestMeta } = {}): Promise<T> {
|
|
156
|
+
return this.request<T>({
|
|
157
|
+
method: 'GET',
|
|
158
|
+
url,
|
|
159
|
+
data,
|
|
160
|
+
header: options.header,
|
|
161
|
+
meta: options.meta
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
post<T = unknown>(url: string, data: any = {}, options: { header?: Record<string, any>; meta?: RequestMeta } = {}): Promise<T> {
|
|
166
|
+
return this.request<T>({
|
|
167
|
+
url,
|
|
157
168
|
method: 'POST',
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
loadingText: '请求中...',
|
|
164
|
-
loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
|
|
165
|
-
timer: null, // 定时器
|
|
166
|
-
originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
|
|
167
|
-
loadingMask: true // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
|
|
168
|
-
};
|
|
169
|
+
data,
|
|
170
|
+
header: options.header,
|
|
171
|
+
meta: options.meta
|
|
172
|
+
});
|
|
173
|
+
}
|
|
169
174
|
|
|
170
|
-
|
|
171
|
-
this.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
put<T = unknown>(url: string, data: any = {}, options: { header?: Record<string, any>; meta?: RequestMeta } = {}): Promise<T> {
|
|
176
|
+
return this.request<T>({
|
|
177
|
+
url,
|
|
178
|
+
method: 'PUT',
|
|
179
|
+
data,
|
|
180
|
+
header: options.header,
|
|
181
|
+
meta: options.meta
|
|
182
|
+
});
|
|
183
|
+
}
|
|
177
184
|
|
|
178
|
-
|
|
179
|
-
this.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
delete<T = unknown>(url: string, data: any = {}, options: { header?: Record<string, any>; meta?: RequestMeta } = {}): Promise<T> {
|
|
186
|
+
return this.request<T>({
|
|
187
|
+
url,
|
|
188
|
+
method: 'DELETE',
|
|
189
|
+
data,
|
|
190
|
+
header: options.header,
|
|
191
|
+
meta: options.meta
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
187
195
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return this.request({
|
|
191
|
-
url,
|
|
192
|
-
method: 'POST',
|
|
193
|
-
header,
|
|
194
|
-
data
|
|
195
|
-
});
|
|
196
|
-
};
|
|
196
|
+
// 插件化导出,支持 app.use(http, { interceptor })
|
|
197
|
+
const httpInstance = new Request();
|
|
197
198
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
method: 'PUT',
|
|
203
|
-
header,
|
|
204
|
-
data
|
|
205
|
-
});
|
|
206
|
-
};
|
|
199
|
+
interface HttpPluginOptions {
|
|
200
|
+
requestConfig?: Partial<RequestConfig>;
|
|
201
|
+
interceptor?: RequestInterceptor;
|
|
202
|
+
}
|
|
207
203
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
204
|
+
// 全局导出,支持 import { httpPlugin } from 'uview-pro'
|
|
205
|
+
const httpPlugin = {
|
|
206
|
+
install(app: any, options: HttpPluginOptions = {}) {
|
|
207
|
+
if (options.interceptor) {
|
|
208
|
+
const { request, response } = options.interceptor;
|
|
209
|
+
if (request) httpInstance.interceptor.request = request;
|
|
210
|
+
if (response) httpInstance.interceptor.response = response;
|
|
211
|
+
}
|
|
212
|
+
if (options.requestConfig) {
|
|
213
|
+
httpInstance.setConfig(options.requestConfig);
|
|
214
|
+
}
|
|
215
|
+
app.config.globalProperties.$http = httpInstance;
|
|
217
216
|
}
|
|
217
|
+
};
|
|
218
218
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
*/
|
|
222
|
-
get: (url: string, data?: any, header?: Record<string, any>) => Promise<any>;
|
|
223
|
-
/**
|
|
224
|
-
* POST 请求
|
|
225
|
-
*/
|
|
226
|
-
post: (url: string, data?: any, header?: Record<string, any>) => Promise<any>;
|
|
227
|
-
/**
|
|
228
|
-
* PUT 请求
|
|
229
|
-
*/
|
|
230
|
-
put: (url: string, data?: any, header?: Record<string, any>) => Promise<any>;
|
|
231
|
-
/**
|
|
232
|
-
* DELETE 请求
|
|
233
|
-
*/
|
|
234
|
-
delete: (url: string, data?: any, header?: Record<string, any>) => Promise<any>;
|
|
235
|
-
}
|
|
219
|
+
// 全局导出,支持 import { http } from 'uview-pro'
|
|
220
|
+
export { httpInstance as http };
|
|
236
221
|
|
|
237
|
-
|
|
222
|
+
// 插件化导出,支持 app.use(http, { interceptor })
|
|
223
|
+
export default httpPlugin;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "uview-pro",
|
|
3
3
|
"name": "uview-pro",
|
|
4
4
|
"displayName": "【Vue3重构版】uView Pro|基于Vue3+TS全面重构的70+精选UI组件库",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.20",
|
|
6
6
|
"description": "uView Pro,是全面支持Vue3的uni-app生态框架,70+精选组件已使用TypeScript重构,已全面支持uni-app Vue3.0",
|
|
7
7
|
"main": "index.ts",
|
|
8
8
|
"module": "index.ts",
|
package/readme.md
CHANGED
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
|
|
26
26
|
## 特性
|
|
27
27
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
28
|
+
- 兼容安卓,iOS,微信小程序,H5,QQ 小程序,百度小程序,支付宝小程序,头条小程序
|
|
29
|
+
- 70+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
|
|
30
|
+
- 众多贴心的 JS 利器,让您飞镖在手,召之即来,百步穿杨
|
|
31
|
+
- 众多的常用页面和布局,让您专注逻辑,事半功倍
|
|
32
|
+
- 详尽的文档支持,现代化的演示效果
|
|
33
|
+
- 按需引入,精简打包体积
|
|
34
34
|
|
|
35
35
|
## 手机预览
|
|
36
36
|
|
|
@@ -58,10 +58,10 @@ pnpm dev
|
|
|
58
58
|
|
|
59
59
|
## 链接
|
|
60
60
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
61
|
+
- [Github](https://github.com/anyup/uview-pro)
|
|
62
|
+
- [Gitee](https://gitee.com/anyup/uview-pro)
|
|
63
|
+
- [官方文档](https://uview-pro.netlify.app/)
|
|
64
|
+
- [更新日志](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)
|
|
65
65
|
|
|
66
66
|
## 交流反馈
|
|
67
67
|
|
|
@@ -69,7 +69,7 @@ pnpm dev
|
|
|
69
69
|
|
|
70
70
|
<table class="table">
|
|
71
71
|
<tr>
|
|
72
|
-
<td><img src="https://ik.imagekit.io/anyup/images/social/weixin-chat
|
|
72
|
+
<td><img src="https://ik.imagekit.io/anyup/images/social/weixin-chat.png?updatedAt=1757299344899" width="250" height="345" ></td>
|
|
73
73
|
<td><img src="https://ik.imagekit.io/anyup/images/social/qq-chat.png" width="250" height="345" ></td>
|
|
74
74
|
</tr>
|
|
75
75
|
<tr>
|
|
@@ -90,7 +90,7 @@ pnpm dev
|
|
|
90
90
|
|
|
91
91
|
### 1. 安装 uView Pro
|
|
92
92
|
|
|
93
|
-
-
|
|
93
|
+
- npm 安装:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
96
|
npm install uview-pro
|
|
@@ -100,7 +100,7 @@ yarn add uview-pro
|
|
|
100
100
|
pnpm add uview-pro
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
-
|
|
103
|
+
- uni_modules 安装:
|
|
104
104
|
|
|
105
105
|
通过 HBuilderX 插件市场或手动下载,将 uView Pro 放入 `uni_modules` 目录。
|
|
106
106
|
|
|
@@ -169,9 +169,9 @@ export function createApp() {
|
|
|
169
169
|
|
|
170
170
|
**温馨提示**
|
|
171
171
|
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
172
|
+
- 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。
|
|
173
|
+
- 2.请确保 `pages.json` 中只有一个 easycom 字段,否则请自行合并多个规则。
|
|
174
|
+
- 3.一定要放在 `custom` 内,否则无效。
|
|
175
175
|
|
|
176
176
|
### 5. Volar 类型提示支持
|
|
177
177
|
|
|
@@ -225,7 +225,7 @@ export function createApp() {
|
|
|
225
225
|
|
|
226
226
|
再次感谢 `uView UI` 开发团队,以及所有为 `uView UI` 的贡献者,以及所有为 `uView Pro` 的贡献者。
|
|
227
227
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
231
|
-
-
|
|
228
|
+
- [Github](https://github.com/anyup/uview-pro)
|
|
229
|
+
- [Gitee](https://gitee.com/anyup/uview-pro)
|
|
230
|
+
- [uView UI 1.0](https://github.com/umicro/uView)
|
|
231
|
+
- [uView UI 2.0](https://github.com/umicro/uView2.0)
|
package/libs/request/uni-http.md
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
# uni-http 使用说明(useHttp hooks 版)
|
|
2
|
-
|
|
3
|
-
> 本文档适用于 uView Pro 3.x 及以上版本,推荐使用 hooks 方式引入 Http 请求库。
|
|
4
|
-
|
|
5
|
-
## 目录
|
|
6
|
-
- [简介](#简介)
|
|
7
|
-
- [快速开始](#快速开始)
|
|
8
|
-
- [类型定义](#类型定义)
|
|
9
|
-
- [拦截器用法](#拦截器用法)
|
|
10
|
-
- [常见用例](#常见用例)
|
|
11
|
-
- [常见问题](#常见问题)
|
|
12
|
-
- [类型提示与 TS 支持](#类型提示与 TS 支持)
|
|
13
|
-
- [FAQ](#faq)
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 简介
|
|
18
|
-
|
|
19
|
-
`uni-http` 是基于 Promise 封装的 uni-app HTTP 请求库,支持全局配置、请求/响应拦截、类型安全、hooks 化调用,适配多端。推荐通过 `useHttp` hooks 工厂函数创建实例,支持全局单例和按需实例化。
|
|
20
|
-
|
|
21
|
-
## 快速开始
|
|
22
|
-
|
|
23
|
-
### 1. 引入 useHttp
|
|
24
|
-
```ts
|
|
25
|
-
import useHttp from '@/uni_modules/uview-pro/libs/request/uni-http';
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### 2. 创建 http 实例
|
|
29
|
-
```ts
|
|
30
|
-
const http = useHttp({
|
|
31
|
-
baseURL: 'https://api.example.com',
|
|
32
|
-
timeout: 10000,
|
|
33
|
-
header: { 'Content-Type': 'application/json' }
|
|
34
|
-
});
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### 3. 发起请求
|
|
38
|
-
```ts
|
|
39
|
-
// GET
|
|
40
|
-
http.get('/user/info', { params: { id: 1 } })
|
|
41
|
-
.then(res => { /* ... */ })
|
|
42
|
-
.catch(err => { /* ... */ });
|
|
43
|
-
|
|
44
|
-
// POST
|
|
45
|
-
http.post('/user/update', { name: '张三' })
|
|
46
|
-
.then(res => { /* ... */ });
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## 类型定义
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
interface HttpRequestConfig {
|
|
53
|
-
baseURL?: string;
|
|
54
|
-
timeout?: number;
|
|
55
|
-
header?: Record<string, any>;
|
|
56
|
-
[key: string]: any;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
interface HttpResponse<T = any> {
|
|
60
|
-
code: number;
|
|
61
|
-
data: T;
|
|
62
|
-
msg: string;
|
|
63
|
-
[key: string]: any;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface Http {
|
|
67
|
-
get<T = any>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
|
|
68
|
-
post<T = any>(url: string, data?: any, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
|
|
69
|
-
put<T = any>(url: string, data?: any, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
|
|
70
|
-
delete<T = any>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
|
|
71
|
-
// ... 其他方法
|
|
72
|
-
setRequestInterceptor(fn: (config: HttpRequestConfig) => HttpRequestConfig | Promise<HttpRequestConfig>): void;
|
|
73
|
-
setResponseInterceptor(fn: (response: HttpResponse) => HttpResponse | Promise<HttpResponse>): void;
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## 拦截器用法
|
|
78
|
-
|
|
79
|
-
### 请求拦截器
|
|
80
|
-
```ts
|
|
81
|
-
http.setRequestInterceptor(config => {
|
|
82
|
-
// 可统一添加 token、日志等
|
|
83
|
-
config.header = config.header || {};
|
|
84
|
-
config.header.Authorization = 'Bearer ' + uni.getStorageSync('token');
|
|
85
|
-
return config;
|
|
86
|
-
});
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### 响应拦截器
|
|
90
|
-
```ts
|
|
91
|
-
http.setResponseInterceptor(response => {
|
|
92
|
-
if (response.code !== 0) {
|
|
93
|
-
uni.showToast({ title: response.msg || '请求失败', icon: 'none' });
|
|
94
|
-
}
|
|
95
|
-
return response;
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## 常见用例
|
|
100
|
-
|
|
101
|
-
### 1. 全局单例
|
|
102
|
-
```ts
|
|
103
|
-
// src/common/http.ts
|
|
104
|
-
import useHttp from '@/uni_modules/uview-pro/libs/request/uni-http';
|
|
105
|
-
const http = useHttp({ baseURL: 'https://api.example.com' });
|
|
106
|
-
export default http;
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### 2. 组件内按需实例化
|
|
110
|
-
```ts
|
|
111
|
-
import useHttp from '@/uni_modules/uview-pro/libs/request/uni-http';
|
|
112
|
-
const http = useHttp();
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### 3. 类型推断
|
|
116
|
-
```ts
|
|
117
|
-
interface UserInfo { id: number; name: string; }
|
|
118
|
-
const res = await http.get<UserInfo>('/user/info');
|
|
119
|
-
console.log(res.data.id);
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### 4. 错误处理
|
|
123
|
-
```ts
|
|
124
|
-
http.get('/error/api').catch(err => {
|
|
125
|
-
uni.showToast({ title: err.message, icon: 'none' });
|
|
126
|
-
});
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## 常见问题
|
|
130
|
-
|
|
131
|
-
- **Q: 如何全局配置 baseURL、header?**
|
|
132
|
-
A: 在 useHttp({ baseURL, header }) 传入即可。
|
|
133
|
-
- **Q: 如何自定义拦截器?**
|
|
134
|
-
A: 通过 setRequestInterceptor/setResponseInterceptor。
|
|
135
|
-
- **Q: 支持多实例吗?**
|
|
136
|
-
A: 支持,useHttp 可多次调用。
|
|
137
|
-
- **Q: 支持类型推断吗?**
|
|
138
|
-
A: 支持,泛型参数自动推断返回数据类型。
|
|
139
|
-
|
|
140
|
-
## 类型提示与 TS 支持
|
|
141
|
-
|
|
142
|
-
- 完全 TypeScript 支持,类型自动推断。
|
|
143
|
-
- 推荐在 `tsconfig.json` 中包含 `uni-http.ts` 路径。
|
|
144
|
-
|
|
145
|
-
## FAQ
|
|
146
|
-
|
|
147
|
-
- **Q: 还能用 new Http() 吗?**
|
|
148
|
-
A: 不推荐,已废弃。请统一使用 useHttp。
|
|
149
|
-
- **Q: 如何清理拦截器?**
|
|
150
|
-
A: 暂不支持移除,建议重新实例化。
|
|
151
|
-
- **Q: 支持 uni.uploadFile、downloadFile 吗?**
|
|
152
|
-
A: 暂未内置,可自行扩展。
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
如有更多问题,欢迎提 Issue 或 PR。
|