uview-pro 0.6.18 → 0.6.19

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.
Files changed (278) hide show
  1. package/changelog.md +1778 -1768
  2. package/components/u-action-sheet/types.ts +52 -52
  3. package/components/u-action-sheet/u-action-sheet.vue +196 -196
  4. package/components/u-action-sheet-item/types.ts +35 -35
  5. package/components/u-action-sheet-item/u-action-sheet-item.vue +85 -85
  6. package/components/u-alert-tips/types.ts +49 -49
  7. package/components/u-alert-tips/u-alert-tips.vue +239 -239
  8. package/components/u-avatar/types.ts +44 -44
  9. package/components/u-avatar/u-avatar.vue +218 -218
  10. package/components/u-avatar-cropper/types.ts +23 -23
  11. package/components/u-avatar-cropper/u-avatar-cropper.vue +299 -299
  12. package/components/u-avatar-cropper/weCropper.d.ts +62 -62
  13. package/components/u-avatar-cropper/weCropper.js +1281 -1281
  14. package/components/u-avatar-cropper/weCropper.ts +1276 -1276
  15. package/components/u-back-top/types.ts +44 -44
  16. package/components/u-back-top/u-back-top.vue +141 -141
  17. package/components/u-badge/types.ts +46 -46
  18. package/components/u-badge/u-badge.vue +153 -153
  19. package/components/u-button/types.ts +76 -76
  20. package/components/u-button/u-button.vue +608 -608
  21. package/components/u-calendar/types.ts +126 -126
  22. package/components/u-calendar/u-calendar.vue +1243 -1243
  23. package/components/u-car-keyboard/types.ts +22 -22
  24. package/components/u-car-keyboard/u-car-keyboard.vue +263 -263
  25. package/components/u-card/types.ts +69 -69
  26. package/components/u-card/u-card.vue +210 -210
  27. package/components/u-cell-group/types.ts +27 -27
  28. package/components/u-cell-group/u-cell-group.vue +60 -60
  29. package/components/u-cell-item/types.ts +64 -64
  30. package/components/u-cell-item/u-cell-item.vue +221 -221
  31. package/components/u-checkbox/types.ts +45 -45
  32. package/components/u-checkbox/u-checkbox.vue +363 -363
  33. package/components/u-checkbox-group/types.ts +45 -45
  34. package/components/u-checkbox-group/u-checkbox-group.vue +172 -172
  35. package/components/u-circle-progress/types.ts +63 -63
  36. package/components/u-circle-progress/u-circle-progress.vue +299 -299
  37. package/components/u-city-select/types.ts +30 -30
  38. package/components/u-city-select/u-city-select.vue +281 -281
  39. package/components/u-col/types.ts +40 -40
  40. package/components/u-col/u-col.vue +142 -142
  41. package/components/u-collapse/types.ts +41 -41
  42. package/components/u-collapse/u-collapse.vue +190 -190
  43. package/components/u-collapse-item/types.ts +35 -35
  44. package/components/u-collapse-item/u-collapse-item.vue +291 -291
  45. package/components/u-column-notice/types.ts +58 -58
  46. package/components/u-column-notice/u-column-notice.vue +223 -223
  47. package/components/u-config-provider/types.ts +53 -53
  48. package/components/u-config-provider/u-config-provider.vue +185 -185
  49. package/components/u-count-down/types.ts +52 -52
  50. package/components/u-count-down/u-count-down.vue +288 -288
  51. package/components/u-count-to/types.ts +42 -42
  52. package/components/u-count-to/u-count-to.vue +266 -266
  53. package/components/u-divider/types.ts +41 -41
  54. package/components/u-divider/u-divider.vue +146 -146
  55. package/components/u-dropdown/types.ts +67 -67
  56. package/components/u-dropdown/u-dropdown.vue +436 -436
  57. package/components/u-dropdown-item/types.ts +40 -40
  58. package/components/u-dropdown-item/u-dropdown-item.vue +124 -124
  59. package/components/u-empty/types.ts +46 -46
  60. package/components/u-empty/u-empty.vue +109 -109
  61. package/components/u-fab/types.ts +83 -83
  62. package/components/u-fab/u-fab.vue +330 -330
  63. package/components/u-field/types.ts +81 -81
  64. package/components/u-field/u-field.vue +398 -398
  65. package/components/u-form/types.ts +39 -39
  66. package/components/u-form/u-form.vue +175 -135
  67. package/components/u-form-item/types.ts +95 -95
  68. package/components/u-form-item/u-form-item.vue +563 -563
  69. package/components/u-full-screen/types.ts +26 -26
  70. package/components/u-full-screen/u-full-screen.vue +100 -100
  71. package/components/u-gap/types.ts +28 -28
  72. package/components/u-gap/u-gap.vue +50 -50
  73. package/components/u-grid/types.ts +29 -29
  74. package/components/u-grid/u-grid.vue +91 -91
  75. package/components/u-grid-item/types.ts +24 -24
  76. package/components/u-grid-item/u-grid-item.vue +130 -130
  77. package/components/u-icon/types.ts +69 -69
  78. package/components/u-icon/u-icon.vue +301 -301
  79. package/components/u-image/types.ts +61 -61
  80. package/components/u-image/u-image.vue +245 -245
  81. package/components/u-index-anchor/types.ts +24 -24
  82. package/components/u-index-anchor/u-index-anchor.vue +120 -120
  83. package/components/u-index-list/types.ts +44 -44
  84. package/components/u-index-list/u-index-list.vue +346 -346
  85. package/components/u-input/types.ts +165 -165
  86. package/components/u-input/u-input.vue +453 -453
  87. package/components/u-keyboard/types.ts +40 -40
  88. package/components/u-keyboard/u-keyboard.vue +201 -201
  89. package/components/u-lazy-load/types.ts +37 -37
  90. package/components/u-lazy-load/u-lazy-load.vue +246 -246
  91. package/components/u-line/types.ts +44 -44
  92. package/components/u-line/u-line.vue +68 -68
  93. package/components/u-line-progress/types.ts +58 -58
  94. package/components/u-line-progress/u-line-progress.vue +131 -131
  95. package/components/u-link/types.ts +54 -54
  96. package/components/u-link/u-link.vue +100 -100
  97. package/components/u-loading/types.ts +45 -45
  98. package/components/u-loading/u-loading.vue +106 -106
  99. package/components/u-loading-popup/types.ts +26 -26
  100. package/components/u-loading-popup/u-loading-popup.vue +254 -254
  101. package/components/u-loadmore/types.ts +88 -88
  102. package/components/u-loadmore/u-loadmore.vue +170 -170
  103. package/components/u-mask/types.ts +48 -48
  104. package/components/u-mask/u-mask.vue +113 -113
  105. package/components/u-message-input/types.ts +90 -90
  106. package/components/u-message-input/u-message-input.vue +283 -283
  107. package/components/u-modal/service.ts +48 -48
  108. package/components/u-modal/types.ts +139 -139
  109. package/components/u-modal/u-modal.vue +465 -465
  110. package/components/u-navbar/types.ts +104 -104
  111. package/components/u-navbar/u-navbar.vue +268 -268
  112. package/components/u-no-network/image.ts +2 -2
  113. package/components/u-no-network/types.ts +29 -29
  114. package/components/u-no-network/u-no-network.vue +313 -313
  115. package/components/u-notice-bar/types.ts +111 -111
  116. package/components/u-notice-bar/u-notice-bar.vue +191 -191
  117. package/components/u-number-box/types.ts +42 -42
  118. package/components/u-number-box/u-number-box.vue +322 -322
  119. package/components/u-number-keyboard/types.ts +26 -26
  120. package/components/u-number-keyboard/u-number-keyboard.vue +189 -189
  121. package/components/u-pagination/types.ts +38 -38
  122. package/components/u-pagination/u-pagination.vue +102 -102
  123. package/components/u-picker/types.ts +140 -140
  124. package/components/u-picker/u-picker.vue +854 -854
  125. package/components/u-popup/types.ts +64 -64
  126. package/components/u-popup/u-popup.vue +427 -427
  127. package/components/u-radio/types.ts +39 -39
  128. package/components/u-radio/u-radio.vue +349 -349
  129. package/components/u-radio-group/types.ts +40 -40
  130. package/components/u-radio-group/u-radio-group.vue +96 -96
  131. package/components/u-rate/types.ts +50 -50
  132. package/components/u-rate/u-rate.vue +250 -250
  133. package/components/u-read-more/types.ts +46 -46
  134. package/components/u-read-more/u-read-more.vue +182 -182
  135. package/components/u-root-portal/u-root-portal.vue +55 -55
  136. package/components/u-row/types.ts +30 -30
  137. package/components/u-row/u-row.vue +105 -105
  138. package/components/u-row-notice/types.ts +49 -49
  139. package/components/u-row-notice/u-row-notice.vue +257 -257
  140. package/components/u-safe-bottom/types.ts +19 -19
  141. package/components/u-safe-bottom/u-safe-bottom.vue +55 -55
  142. package/components/u-search/u-search.vue +297 -297
  143. package/components/u-section/types.ts +42 -42
  144. package/components/u-section/u-section.vue +156 -156
  145. package/components/u-select/types.ts +56 -56
  146. package/components/u-select/u-select.vue +447 -447
  147. package/components/u-skeleton/types.ts +89 -89
  148. package/components/u-skeleton/u-skeleton.vue +253 -253
  149. package/components/u-slider/types.ts +55 -55
  150. package/components/u-slider/u-slider.vue +422 -422
  151. package/components/u-status-bar/types.ts +21 -21
  152. package/components/u-status-bar/u-status-bar.vue +64 -64
  153. package/components/u-step/types.ts +37 -37
  154. package/components/u-step/u-step.vue +292 -292
  155. package/components/u-steps/types.ts +39 -39
  156. package/components/u-steps/u-steps.vue +105 -105
  157. package/components/u-sticky/types.ts +33 -33
  158. package/components/u-sticky/u-sticky.vue +177 -177
  159. package/components/u-subsection/types.ts +46 -46
  160. package/components/u-subsection/u-subsection.vue +358 -358
  161. package/components/u-swipe-action/types.ts +60 -60
  162. package/components/u-swipe-action/u-swipe-action.vue +276 -276
  163. package/components/u-swiper/types.ts +57 -57
  164. package/components/u-swiper/u-swiper.vue +308 -308
  165. package/components/u-switch/types.ts +39 -39
  166. package/components/u-switch/u-switch.vue +212 -212
  167. package/components/u-tabbar/types.ts +57 -57
  168. package/components/u-tabbar/u-tabbar.vue +480 -480
  169. package/components/u-table/types.ts +35 -35
  170. package/components/u-table/u-table.vue +67 -67
  171. package/components/u-tabs/types.ts +64 -64
  172. package/components/u-tabs/u-tabs.vue +328 -328
  173. package/components/u-tabs-swiper/types.ts +64 -64
  174. package/components/u-tabs-swiper/u-tabs-swiper.vue +407 -407
  175. package/components/u-tag/types.ts +47 -47
  176. package/components/u-tag/u-tag.vue +276 -276
  177. package/components/u-td/types.ts +22 -22
  178. package/components/u-td/u-td.vue +65 -65
  179. package/components/u-text/types.ts +80 -80
  180. package/components/u-text/u-text.vue +355 -355
  181. package/components/u-textarea/types.ts +105 -105
  182. package/components/u-textarea/u-textarea.vue +450 -450
  183. package/components/u-th/types.ts +22 -22
  184. package/components/u-th/u-th.vue +63 -63
  185. package/components/u-time-line/u-time-line.vue +64 -64
  186. package/components/u-time-line-item/types.ts +24 -24
  187. package/components/u-time-line-item/u-time-line-item.vue +89 -89
  188. package/components/u-toast/service.ts +40 -40
  189. package/components/u-toast/types.ts +54 -54
  190. package/components/u-toast/u-toast.vue +385 -385
  191. package/components/u-top-tips/types.ts +25 -25
  192. package/components/u-top-tips/u-top-tips.vue +130 -130
  193. package/components/u-tr/types.ts +19 -19
  194. package/components/u-tr/u-tr.vue +39 -39
  195. package/components/u-transition/types.ts +43 -43
  196. package/components/u-transition/u-transition.vue +437 -437
  197. package/components/u-upload/types.ts +171 -171
  198. package/components/u-upload/u-upload.vue +1605 -1605
  199. package/components/u-verification-code/types.ts +32 -32
  200. package/components/u-verification-code/u-verification-code.vue +183 -183
  201. package/components/u-waterfall/types.ts +26 -26
  202. package/components/u-waterfall/u-waterfall.vue +188 -188
  203. package/iconfont.css +913 -913
  204. package/index.scss +26 -26
  205. package/libs/config/color.ts +9 -9
  206. package/libs/config/config.ts +59 -59
  207. package/libs/config/theme-tokens.ts +102 -102
  208. package/libs/config/zIndex.ts +32 -32
  209. package/libs/css/color.scss +155 -155
  210. package/libs/css/common.scss +183 -183
  211. package/libs/css/style.components.scss +16 -16
  212. package/libs/css/style.h5.scss +8 -8
  213. package/libs/css/style.mp.scss +68 -68
  214. package/libs/css/style.nvue.scss +15 -15
  215. package/libs/css/style.theme.scss +56 -56
  216. package/libs/css/style.vue.scss +188 -188
  217. package/libs/function/$parent.ts +24 -24
  218. package/libs/function/addUnit.ts +50 -50
  219. package/libs/function/clipboard.ts +73 -73
  220. package/libs/function/color.ts +28 -28
  221. package/libs/function/colorGradient.ts +139 -139
  222. package/libs/function/debounce.ts +28 -28
  223. package/libs/function/deepClone.ts +39 -39
  224. package/libs/function/deepMerge.ts +35 -35
  225. package/libs/function/getParent.ts +63 -63
  226. package/libs/function/getRect.ts +26 -26
  227. package/libs/function/guid.ts +42 -42
  228. package/libs/function/md5.ts +403 -403
  229. package/libs/function/parent.ts +21 -21
  230. package/libs/function/queryParams.ts +64 -64
  231. package/libs/function/random.ts +16 -16
  232. package/libs/function/randomArray.ts +11 -11
  233. package/libs/function/route.ts +118 -118
  234. package/libs/function/styleUtils.ts +83 -83
  235. package/libs/function/sys.ts +15 -15
  236. package/libs/function/test.ts +289 -289
  237. package/libs/function/throttle.ts +31 -31
  238. package/libs/function/timeFormat.ts +55 -55
  239. package/libs/function/timeFrom.ts +48 -48
  240. package/libs/function/toast.ts +14 -14
  241. package/libs/function/trim.ts +21 -21
  242. package/libs/function/type2icon.ts +38 -38
  243. package/libs/hooks/index.ts +10 -10
  244. package/libs/hooks/useColor.ts +61 -61
  245. package/libs/hooks/useCompRelation.ts +424 -424
  246. package/libs/hooks/useDebounce.ts +15 -15
  247. package/libs/hooks/useEmitter.ts +79 -79
  248. package/libs/hooks/useLocale.ts +34 -34
  249. package/libs/hooks/useModal.ts +131 -131
  250. package/libs/hooks/useRect.ts +40 -40
  251. package/libs/hooks/useRouter.ts +173 -173
  252. package/libs/hooks/useTheme.ts +173 -173
  253. package/libs/hooks/useThrottle.ts +16 -16
  254. package/libs/hooks/useToast.ts +115 -115
  255. package/libs/index.ts +349 -349
  256. package/libs/request/auto-http.ts +76 -76
  257. package/libs/request/index.ts +301 -301
  258. package/libs/store/index.ts +88 -88
  259. package/libs/util/async-validator.d.ts +75 -75
  260. package/libs/util/async-validator.js +1 -1
  261. package/libs/util/calendar.d.ts +57 -57
  262. package/libs/util/canvas-2d.ts +182 -182
  263. package/libs/util/config-provider.ts +804 -804
  264. package/libs/util/emitter.ts +112 -112
  265. package/libs/util/mitt.ts +118 -118
  266. package/libs/util/system-theme.ts +25 -25
  267. package/locale/index.ts +2 -2
  268. package/locale/lang/en-US.ts +136 -136
  269. package/locale/lang/zh-CN.ts +136 -136
  270. package/package.json +1 -1
  271. package/plugins/root/page.ts +77 -77
  272. package/plugins/root/root.ts +53 -53
  273. package/theme.scss +149 -149
  274. package/types/components.d.ts +105 -105
  275. package/types/global.d.ts +470 -470
  276. package/types/ignore-errors.d.ts +30 -30
  277. package/types/index.d.ts +15 -15
  278. package/types/uni-app.d.ts +63 -63
@@ -1,301 +1,301 @@
1
- import deepMerge from '../function/deepMerge';
2
-
3
- /**
4
- * 请求配置项Meta类型定义
5
- */
6
- export interface RequestMeta {
7
- toast?: boolean;
8
- loading?: boolean;
9
- originalData?: boolean;
10
- [key: string]: any;
11
- }
12
-
13
- /**
14
- * 请求配置项类型定义
15
- */
16
- export interface RequestConfig {
17
- baseUrl?: string;
18
- header?: Record<string, any>;
19
- method?: string;
20
- dataType?: string;
21
- responseType?: string;
22
- timeout?: number;
23
- meta?: RequestMeta;
24
- [key: string]: any;
25
- }
26
-
27
- /**
28
- * 忽略的请求参数类型定义
29
- */
30
- const IGNORE_REQUEST_KEYS = ['baseUrl', 'meta'];
31
-
32
- /**
33
- * 请求拦截器类型定义
34
- */
35
- export interface RequestInterceptor {
36
- request?: ((options: RequestOptions) => RequestOptions | false) | null;
37
- response?: ((response: any) => any | false) | null;
38
- }
39
-
40
- /**
41
- * 请求参数类型定义
42
- */
43
- export interface RequestOptions {
44
- url: string;
45
- header: Record<string, any>;
46
- method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
47
- data?: any;
48
- dataType?: string;
49
- responseType?: string;
50
- params?: Record<string, any>;
51
- complete?: (response: any) => void;
52
- meta?: RequestMeta;
53
- [key: string]: any;
54
- }
55
-
56
- export class Request {
57
- public config: RequestConfig;
58
- public interceptor: RequestInterceptor;
59
- public options?: RequestOptions;
60
-
61
- constructor() {
62
- this.config = {
63
- baseUrl: '', // 请求的根域名
64
- header: {}, // 默认的请求头
65
- method: 'POST', // 请求方式
66
- dataType: 'json', // 设置为json,返回后uni.request会对数据进行一次JSON.parse
67
- responseType: 'text', // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
68
- timeout: 60000,
69
- meta: {
70
- originalData: true, // 是否在拦截器中返回服务端的原始数据,见文档说明
71
- toast: false, // 是否在请求出错时,弹出toast
72
- loading: false // 是否显示加载中
73
- }
74
- };
75
- this.interceptor = {
76
- request: null,
77
- response: null
78
- };
79
- }
80
- /**
81
- * 将全局配置合并到本次请求的 options 中
82
- * - 忽略 IGNORE_REQUEST_KEYS 中的字段(如 meta)
83
- * - 对 header 使用深合并(全局 header 为默认,options.header 优先)
84
- * - 对对象类型的字段尝试深合并,基础类型以 options 值优先
85
- * - 处理 baseUrl:若存在全局 baseUrl 且 options.url 非完整 url(非 http 开头),则合并成完整 URL
86
- */
87
- private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions {
88
- const mergedOptions: RequestOptions = { ...options };
89
- for (const key of Object.keys(this.config)) {
90
- if (IGNORE_REQUEST_KEYS.includes(key)) {
91
- continue;
92
- }
93
- const cfgVal = this.config[key];
94
- const optVal = options[key];
95
-
96
- // 跳过未设置的全局配置
97
- if (cfgVal === undefined) continue;
98
-
99
- // header 需要做深合并,且以 options.header 为准覆盖同名属性
100
- if (key === 'header') {
101
- mergedOptions.header = deepMerge(cfgVal || {}, optVal || {});
102
- continue;
103
- }
104
-
105
- // 针对 method 等枚举字符串,优先使用 options 中的值,否则使用全局配置
106
- if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') {
107
- mergedOptions[key] = optVal !== undefined ? optVal : cfgVal;
108
- continue;
109
- }
110
-
111
- // 对对象类型的配置(如自定义扩展)尝试做深合并
112
- if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) {
113
- mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {});
114
- continue;
115
- }
116
-
117
- // 其他类型,若 options 未传入则使用全局配置
118
- if (optVal === undefined) {
119
- mergedOptions[key] = cfgVal;
120
- }
121
- }
122
- // 如果存在 baseUrl,并且 options.url 为相对地址,则拼接成完整 url
123
- const baseUrl = this.config.baseUrl;
124
- if (
125
- baseUrl &&
126
- mergedOptions.url &&
127
- typeof mergedOptions.url === 'string' &&
128
- mergedOptions.url.indexOf('http') !== 0
129
- ) {
130
- mergedOptions.url =
131
- baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`);
132
- }
133
- // 确保 url 存在,且为 string
134
- if (!mergedOptions.url) {
135
- mergedOptions.url = '';
136
- }
137
- return mergedOptions;
138
- }
139
- /**
140
- * 设置全局默认配置
141
- * @param customConfig 自定义配置
142
- */
143
- setConfig(customConfig: Partial<RequestConfig>): void {
144
- this.config = deepMerge(this.config, customConfig);
145
- }
146
-
147
- /**
148
- * 主要请求部分
149
- * @param options 请求参数
150
- */
151
- request<T = unknown>(options: RequestOptions): Promise<T> {
152
- // 合并 meta 配置,优先级:单次请求 > 全局
153
- const mergedMeta: RequestMeta = {
154
- ...this.config.meta,
155
- ...(options.meta || {})
156
- };
157
- // 让 options.meta 传递到拦截器
158
- options.meta = mergedMeta;
159
- options.url = options.url || '';
160
- options.params = options.params || {};
161
- // 将全局配置合并到本次请求 options 中(注意忽略一些特殊字段如 baseUrl/meta)
162
- options = this.mergeGlobalConfigToOptions(options);
163
-
164
- if (this.interceptor.request && typeof this.interceptor.request === 'function') {
165
- const interceptorRequest = this.interceptor.request(options);
166
- if (!interceptorRequest) {
167
- // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
168
- return new Promise(() => {});
169
- }
170
- this.options = interceptorRequest;
171
- }
172
-
173
- return new Promise<T>((resolve, reject) => {
174
- options.complete = (response: any) => {
175
- // 读取 meta 配置
176
- const meta = options.meta || this.config.meta || {};
177
- const originalData = meta.originalData ?? false;
178
- // 拦截器处理,加入request的配置参数
179
- response.config = options;
180
- if (originalData) {
181
- // 判断是否存在拦截器
182
- if (this.interceptor.response && typeof this.interceptor.response === 'function') {
183
- const resInterceptors = this.interceptor.response(response);
184
- // 如果拦截器不返回false,就将拦截器返回的内容给请求的then回调
185
- if (resInterceptors !== false) {
186
- resolve(resInterceptors);
187
- } else {
188
- // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
189
- reject(response);
190
- }
191
- } else {
192
- // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
193
- resolve(response);
194
- }
195
- } else {
196
- if (response.statusCode === 200) {
197
- if (this.interceptor.response && typeof this.interceptor.response === 'function') {
198
- const resInterceptors = this.interceptor.response(response.data);
199
- if (resInterceptors !== false) {
200
- resolve(resInterceptors);
201
- } else {
202
- reject(response.data);
203
- }
204
- } else {
205
- // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
206
- resolve(response.data);
207
- }
208
- } else {
209
- reject(response);
210
- }
211
- }
212
- };
213
- uni.request(options);
214
- });
215
- }
216
-
217
- get<T = unknown>(
218
- url: string,
219
- data: any = {},
220
- options: { header?: Record<string, any>; meta?: RequestMeta } = {}
221
- ): Promise<T> {
222
- return this.request<T>({
223
- method: 'GET',
224
- url,
225
- data,
226
- header: options.header || {},
227
- meta: options.meta
228
- });
229
- }
230
-
231
- post<T = unknown>(
232
- url: string,
233
- data: any = {},
234
- options: { header?: Record<string, any>; meta?: RequestMeta } = {}
235
- ): Promise<T> {
236
- return this.request<T>({
237
- url,
238
- method: 'POST',
239
- data,
240
- header: options.header || {},
241
- meta: options.meta
242
- });
243
- }
244
-
245
- put<T = unknown>(
246
- url: string,
247
- data: any = {},
248
- options: { header?: Record<string, any>; meta?: RequestMeta } = {}
249
- ): Promise<T> {
250
- return this.request<T>({
251
- url,
252
- method: 'PUT',
253
- data,
254
- header: options.header || {},
255
- meta: options.meta
256
- });
257
- }
258
-
259
- delete<T = unknown>(
260
- url: string,
261
- data: any = {},
262
- options: { header?: Record<string, any>; meta?: RequestMeta } = {}
263
- ): Promise<T> {
264
- return this.request<T>({
265
- url,
266
- method: 'DELETE',
267
- data,
268
- header: options.header || {},
269
- meta: options.meta
270
- });
271
- }
272
- }
273
-
274
- // 插件化导出,支持 app.use(http, { interceptor })
275
- const httpInstance = new Request();
276
-
277
- interface HttpPluginOptions {
278
- requestConfig?: Partial<RequestConfig>;
279
- interceptor?: RequestInterceptor;
280
- }
281
-
282
- // 全局导出,支持 import { httpPlugin } from 'uview-pro'
283
- const httpPlugin = {
284
- install(app: any, options: HttpPluginOptions = {}) {
285
- if (options.interceptor) {
286
- const { request, response } = options.interceptor;
287
- if (request) httpInstance.interceptor.request = request;
288
- if (response) httpInstance.interceptor.response = response;
289
- }
290
- if (options.requestConfig) {
291
- httpInstance.setConfig(options.requestConfig);
292
- }
293
- app.config.globalProperties.$http = httpInstance;
294
- }
295
- };
296
-
297
- // 全局导出,支持 import { http } from 'uview-pro'
298
- export { httpInstance as http };
299
-
300
- // 插件化导出,支持 app.use(http, { interceptor })
301
- export default httpPlugin;
1
+ import deepMerge from '../function/deepMerge';
2
+
3
+ /**
4
+ * 请求配置项Meta类型定义
5
+ */
6
+ export interface RequestMeta {
7
+ toast?: boolean;
8
+ loading?: boolean;
9
+ originalData?: boolean;
10
+ [key: string]: any;
11
+ }
12
+
13
+ /**
14
+ * 请求配置项类型定义
15
+ */
16
+ export interface RequestConfig {
17
+ baseUrl?: string;
18
+ header?: Record<string, any>;
19
+ method?: string;
20
+ dataType?: string;
21
+ responseType?: string;
22
+ timeout?: number;
23
+ meta?: RequestMeta;
24
+ [key: string]: any;
25
+ }
26
+
27
+ /**
28
+ * 忽略的请求参数类型定义
29
+ */
30
+ const IGNORE_REQUEST_KEYS = ['baseUrl', 'meta'];
31
+
32
+ /**
33
+ * 请求拦截器类型定义
34
+ */
35
+ export interface RequestInterceptor {
36
+ request?: ((options: RequestOptions) => RequestOptions | false) | null;
37
+ response?: ((response: any) => any | false) | null;
38
+ }
39
+
40
+ /**
41
+ * 请求参数类型定义
42
+ */
43
+ export interface RequestOptions {
44
+ url: string;
45
+ header: Record<string, any>;
46
+ method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';
47
+ data?: any;
48
+ dataType?: string;
49
+ responseType?: string;
50
+ params?: Record<string, any>;
51
+ complete?: (response: any) => void;
52
+ meta?: RequestMeta;
53
+ [key: string]: any;
54
+ }
55
+
56
+ export class Request {
57
+ public config: RequestConfig;
58
+ public interceptor: RequestInterceptor;
59
+ public options?: RequestOptions;
60
+
61
+ constructor() {
62
+ this.config = {
63
+ baseUrl: '', // 请求的根域名
64
+ header: {}, // 默认的请求头
65
+ method: 'POST', // 请求方式
66
+ dataType: 'json', // 设置为json,返回后uni.request会对数据进行一次JSON.parse
67
+ responseType: 'text', // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
68
+ timeout: 60000,
69
+ meta: {
70
+ originalData: true, // 是否在拦截器中返回服务端的原始数据,见文档说明
71
+ toast: false, // 是否在请求出错时,弹出toast
72
+ loading: false // 是否显示加载中
73
+ }
74
+ };
75
+ this.interceptor = {
76
+ request: null,
77
+ response: null
78
+ };
79
+ }
80
+ /**
81
+ * 将全局配置合并到本次请求的 options 中
82
+ * - 忽略 IGNORE_REQUEST_KEYS 中的字段(如 meta)
83
+ * - 对 header 使用深合并(全局 header 为默认,options.header 优先)
84
+ * - 对对象类型的字段尝试深合并,基础类型以 options 值优先
85
+ * - 处理 baseUrl:若存在全局 baseUrl 且 options.url 非完整 url(非 http 开头),则合并成完整 URL
86
+ */
87
+ private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions {
88
+ const mergedOptions: RequestOptions = { ...options };
89
+ for (const key of Object.keys(this.config)) {
90
+ if (IGNORE_REQUEST_KEYS.includes(key)) {
91
+ continue;
92
+ }
93
+ const cfgVal = this.config[key];
94
+ const optVal = options[key];
95
+
96
+ // 跳过未设置的全局配置
97
+ if (cfgVal === undefined) continue;
98
+
99
+ // header 需要做深合并,且以 options.header 为准覆盖同名属性
100
+ if (key === 'header') {
101
+ mergedOptions.header = deepMerge(cfgVal || {}, optVal || {});
102
+ continue;
103
+ }
104
+
105
+ // 针对 method 等枚举字符串,优先使用 options 中的值,否则使用全局配置
106
+ if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') {
107
+ mergedOptions[key] = optVal !== undefined ? optVal : cfgVal;
108
+ continue;
109
+ }
110
+
111
+ // 对对象类型的配置(如自定义扩展)尝试做深合并
112
+ if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) {
113
+ mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {});
114
+ continue;
115
+ }
116
+
117
+ // 其他类型,若 options 未传入则使用全局配置
118
+ if (optVal === undefined) {
119
+ mergedOptions[key] = cfgVal;
120
+ }
121
+ }
122
+ // 如果存在 baseUrl,并且 options.url 为相对地址,则拼接成完整 url
123
+ const baseUrl = this.config.baseUrl;
124
+ if (
125
+ baseUrl &&
126
+ mergedOptions.url &&
127
+ typeof mergedOptions.url === 'string' &&
128
+ mergedOptions.url.indexOf('http') !== 0
129
+ ) {
130
+ mergedOptions.url =
131
+ baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`);
132
+ }
133
+ // 确保 url 存在,且为 string
134
+ if (!mergedOptions.url) {
135
+ mergedOptions.url = '';
136
+ }
137
+ return mergedOptions;
138
+ }
139
+ /**
140
+ * 设置全局默认配置
141
+ * @param customConfig 自定义配置
142
+ */
143
+ setConfig(customConfig: Partial<RequestConfig>): void {
144
+ this.config = deepMerge(this.config, customConfig);
145
+ }
146
+
147
+ /**
148
+ * 主要请求部分
149
+ * @param options 请求参数
150
+ */
151
+ request<T = unknown>(options: RequestOptions): Promise<T> {
152
+ // 合并 meta 配置,优先级:单次请求 > 全局
153
+ const mergedMeta: RequestMeta = {
154
+ ...this.config.meta,
155
+ ...(options.meta || {})
156
+ };
157
+ // 让 options.meta 传递到拦截器
158
+ options.meta = mergedMeta;
159
+ options.url = options.url || '';
160
+ options.params = options.params || {};
161
+ // 将全局配置合并到本次请求 options 中(注意忽略一些特殊字段如 baseUrl/meta)
162
+ options = this.mergeGlobalConfigToOptions(options);
163
+
164
+ if (this.interceptor.request && typeof this.interceptor.request === 'function') {
165
+ const interceptorRequest = this.interceptor.request(options);
166
+ if (!interceptorRequest) {
167
+ // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
168
+ return new Promise(() => {});
169
+ }
170
+ this.options = interceptorRequest;
171
+ }
172
+
173
+ return new Promise<T>((resolve, reject) => {
174
+ options.complete = (response: any) => {
175
+ // 读取 meta 配置
176
+ const meta = options.meta || this.config.meta || {};
177
+ const originalData = meta.originalData ?? false;
178
+ // 拦截器处理,加入request的配置参数
179
+ response.config = options;
180
+ if (originalData) {
181
+ // 判断是否存在拦截器
182
+ if (this.interceptor.response && typeof this.interceptor.response === 'function') {
183
+ const resInterceptors = this.interceptor.response(response);
184
+ // 如果拦截器不返回false,就将拦截器返回的内容给请求的then回调
185
+ if (resInterceptors !== false) {
186
+ resolve(resInterceptors);
187
+ } else {
188
+ // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
189
+ reject(response);
190
+ }
191
+ } else {
192
+ // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
193
+ resolve(response);
194
+ }
195
+ } else {
196
+ if (response.statusCode === 200) {
197
+ if (this.interceptor.response && typeof this.interceptor.response === 'function') {
198
+ const resInterceptors = this.interceptor.response(response.data);
199
+ if (resInterceptors !== false) {
200
+ resolve(resInterceptors);
201
+ } else {
202
+ reject(response.data);
203
+ }
204
+ } else {
205
+ // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
206
+ resolve(response.data);
207
+ }
208
+ } else {
209
+ reject(response);
210
+ }
211
+ }
212
+ };
213
+ uni.request(options);
214
+ });
215
+ }
216
+
217
+ get<T = unknown>(
218
+ url: string,
219
+ data: any = {},
220
+ options: { header?: Record<string, any>; meta?: RequestMeta } = {}
221
+ ): Promise<T> {
222
+ return this.request<T>({
223
+ method: 'GET',
224
+ url,
225
+ data,
226
+ header: options.header || {},
227
+ meta: options.meta
228
+ });
229
+ }
230
+
231
+ post<T = unknown>(
232
+ url: string,
233
+ data: any = {},
234
+ options: { header?: Record<string, any>; meta?: RequestMeta } = {}
235
+ ): Promise<T> {
236
+ return this.request<T>({
237
+ url,
238
+ method: 'POST',
239
+ data,
240
+ header: options.header || {},
241
+ meta: options.meta
242
+ });
243
+ }
244
+
245
+ put<T = unknown>(
246
+ url: string,
247
+ data: any = {},
248
+ options: { header?: Record<string, any>; meta?: RequestMeta } = {}
249
+ ): Promise<T> {
250
+ return this.request<T>({
251
+ url,
252
+ method: 'PUT',
253
+ data,
254
+ header: options.header || {},
255
+ meta: options.meta
256
+ });
257
+ }
258
+
259
+ delete<T = unknown>(
260
+ url: string,
261
+ data: any = {},
262
+ options: { header?: Record<string, any>; meta?: RequestMeta } = {}
263
+ ): Promise<T> {
264
+ return this.request<T>({
265
+ url,
266
+ method: 'DELETE',
267
+ data,
268
+ header: options.header || {},
269
+ meta: options.meta
270
+ });
271
+ }
272
+ }
273
+
274
+ // 插件化导出,支持 app.use(http, { interceptor })
275
+ const httpInstance = new Request();
276
+
277
+ interface HttpPluginOptions {
278
+ requestConfig?: Partial<RequestConfig>;
279
+ interceptor?: RequestInterceptor;
280
+ }
281
+
282
+ // 全局导出,支持 import { httpPlugin } from 'uview-pro'
283
+ const httpPlugin = {
284
+ install(app: any, options: HttpPluginOptions = {}) {
285
+ if (options.interceptor) {
286
+ const { request, response } = options.interceptor;
287
+ if (request) httpInstance.interceptor.request = request;
288
+ if (response) httpInstance.interceptor.response = response;
289
+ }
290
+ if (options.requestConfig) {
291
+ httpInstance.setConfig(options.requestConfig);
292
+ }
293
+ app.config.globalProperties.$http = httpInstance;
294
+ }
295
+ };
296
+
297
+ // 全局导出,支持 import { http } from 'uview-pro'
298
+ export { httpInstance as http };
299
+
300
+ // 插件化导出,支持 app.use(http, { interceptor })
301
+ export default httpPlugin;