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.
@@ -1,21 +1,25 @@
1
1
  import deepMerge from '../function/deepMerge';
2
- import validate from '../function/test';
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: string;
9
- header: Record<string, any>;
10
- method: string;
11
- dataType: string;
12
- responseType: string;
13
- showLoading: boolean;
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<any> {
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
- let interceptorRequest = this.interceptor.request(options);
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<any>((resolve, reject) => {
109
+ return new Promise<T>((resolve, reject) => {
81
110
  options.complete = (response: any) => {
82
- // 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
83
- uni.hideLoading();
84
- // 清除定时器,如果请求回来了,就无需loading
85
- clearTimeout(this.config.timer as ReturnType<typeof setTimeout>);
86
- this.config.timer = null;
87
- // 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data
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
- let resInterceptors = this.interceptor.response(response);
92
- // 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
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 == 200) {
132
+ if (response.statusCode === 200) {
105
133
  if (this.interceptor.response && typeof this.interceptor.response === 'function') {
106
- let resInterceptors = this.interceptor.response(response.data);
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
- // 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
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
- constructor() {
153
- this.config = {
154
- baseUrl: '', // 请求的根域名
155
- // 默认的请求头
156
- header: {},
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
- // 设置为json,返回后uni.request会对数据进行一次JSON.parse
159
- dataType: 'json',
160
- // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
161
- responseType: 'text',
162
- showLoading: true, // 是否显示请求中的loading
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.interceptor = {
172
- // 请求前的拦截
173
- request: null,
174
- // 请求后的拦截
175
- response: null
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
- // get请求
179
- this.get = (url: string, data: any = {}, header: Record<string, any> = {}): Promise<any> => {
180
- return this.request({
181
- method: 'GET',
182
- url,
183
- header,
184
- data
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
- // post请求
189
- this.post = (url: string, data: any = {}, header: Record<string, any> = {}): Promise<any> => {
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
- // put请求,不支持支付宝小程序(HX2.6.15)
199
- this.put = (url: string, data: any = {}, header: Record<string, any> = {}): Promise<any> => {
200
- return this.request({
201
- url,
202
- method: 'PUT',
203
- header,
204
- data
205
- });
206
- };
199
+ interface HttpPluginOptions {
200
+ requestConfig?: Partial<RequestConfig>;
201
+ interceptor?: RequestInterceptor;
202
+ }
207
203
 
208
- // delete请求,不支持支付宝和头条小程序(HX2.6.15)
209
- this.delete = (url: string, data: any = {}, header: Record<string, any> = {}): Promise<any> => {
210
- return this.request({
211
- url,
212
- method: 'DELETE',
213
- header,
214
- data
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
- * GET 请求
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
- export default new Request();
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.18",
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
- - 兼容安卓,iOS,微信小程序,H5,QQ 小程序,百度小程序,支付宝小程序,头条小程序
29
- - 70+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
30
- - 众多贴心的 JS 利器,让您飞镖在手,召之即来,百步穿杨
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
- - [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)
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-2.png?updatedAt=1756355426929" width="250" height="345" ></td>
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
- - npm 安装:
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
- - uni_modules 安装:
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
- - 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。
173
- - 2.请确保 `pages.json` 中只有一个 easycom 字段,否则请自行合并多个规则。
174
- - 3.一定要放在 `custom` 内,否则无效。
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
- - [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)
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)
@@ -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。