vite-uni-dev-tool 1.0.0 → 1.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.
Files changed (168) hide show
  1. package/README.md +46 -0
  2. package/dist/const.cjs +1 -1
  3. package/dist/const.d.ts +12 -0
  4. package/dist/const.d.ts.map +1 -1
  5. package/dist/const.js +1 -1
  6. package/dist/core-shared.d.ts +1 -1
  7. package/dist/core-shared.d.ts.map +1 -1
  8. package/dist/core-shared.js +1 -1
  9. package/dist/core.d.ts +10 -3
  10. package/dist/core.d.ts.map +1 -1
  11. package/dist/core.js +2 -2
  12. package/dist/i18n/locales/en.cjs +1 -1
  13. package/dist/i18n/locales/en.d.ts +81 -0
  14. package/dist/i18n/locales/en.d.ts.map +1 -1
  15. package/dist/i18n/locales/en.js +1 -1
  16. package/dist/i18n/locales/zh-Hans.cjs +1 -1
  17. package/dist/i18n/locales/zh-Hans.d.ts +82 -1
  18. package/dist/i18n/locales/zh-Hans.d.ts.map +1 -1
  19. package/dist/i18n/locales/zh-Hans.js +1 -1
  20. package/dist/modules/devConsole/index.cjs +1 -1
  21. package/dist/modules/devConsole/index.js +3 -3
  22. package/dist/modules/devEvent/index.cjs +3 -3
  23. package/dist/modules/devEvent/index.d.ts +1 -0
  24. package/dist/modules/devEvent/index.d.ts.map +1 -1
  25. package/dist/modules/devEvent/index.js +3 -3
  26. package/dist/modules/devIntercept/index.cjs +14 -13
  27. package/dist/modules/devIntercept/index.d.ts +19 -0
  28. package/dist/modules/devIntercept/index.d.ts.map +1 -1
  29. package/dist/modules/devIntercept/index.js +14 -13
  30. package/dist/modules/devStore/index.cjs +1 -1
  31. package/dist/modules/devStore/index.d.ts +21 -0
  32. package/dist/modules/devStore/index.d.ts.map +1 -1
  33. package/dist/modules/devStore/index.js +1 -1
  34. package/dist/plugins/uniDevTool/transform/transformMain.cjs +1 -1
  35. package/dist/plugins/uniDevTool/transform/transformMain.js +1 -1
  36. package/dist/type.d.ts +47 -2
  37. package/dist/type.d.ts.map +1 -1
  38. package/dist/utils/language.cjs +1 -1
  39. package/dist/utils/language.d.ts.map +1 -1
  40. package/dist/utils/language.js +1 -1
  41. package/dist/utils/object.cjs +1 -1
  42. package/dist/utils/object.d.ts.map +1 -1
  43. package/dist/utils/object.js +1 -1
  44. package/dist/v3/DevTool/components/BluetoothList/BluetoothItem.vue +199 -0
  45. package/dist/v3/DevTool/components/BluetoothList/BluetoothTool.vue +730 -0
  46. package/dist/v3/DevTool/components/BluetoothList/index.vue +167 -0
  47. package/dist/v3/{CaptureScreen → DevTool/components/CaptureScreen}/index.vue +109 -109
  48. package/dist/v3/{ConsoleList → DevTool/components/ConsoleList}/ConsoleItem.vue +225 -224
  49. package/dist/v3/{ConsoleList → DevTool/components/ConsoleList}/RunJSInput.vue +247 -249
  50. package/dist/v3/{ConsoleList → DevTool/components/ConsoleList}/index.vue +171 -160
  51. package/dist/v3/{ConsoleList → DevTool/components/ConsoleList}/staticTips.ts +1145 -1145
  52. package/dist/v3/{DevToolButton → DevTool/components/DevToolButton}/index.vue +7 -4
  53. package/dist/v3/{DevToolTitle → DevTool/components/DevToolTitle}/index.vue +24 -24
  54. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/DevToolOverlay.vue +197 -182
  55. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/const.ts +28 -5
  56. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/hooks/dataUtils.ts +48 -48
  57. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/hooks/useDevToolData.ts +387 -338
  58. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/hooks/useDevToolHandlers.ts +629 -549
  59. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/hooks/useDevToolOverlay.ts +197 -184
  60. package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/index.vue +67 -16
  61. package/dist/v3/{ElEvent → DevTool/components/ElEvent}/ElEventItem.vue +105 -105
  62. package/dist/v3/{ElEvent → DevTool/components/ElEvent}/index.vue +106 -109
  63. package/dist/v3/{Instance → DevTool/components/Instance}/components/InstanceTreeNode.vue +265 -265
  64. package/dist/v3/{Instance → DevTool/components/Instance}/flatten.ts +226 -226
  65. package/dist/v3/{Instance → DevTool/components/Instance}/index.vue +94 -94
  66. package/dist/v3/{Instance → DevTool/components/Instance}/registry.ts +49 -49
  67. package/dist/v3/{Instance → DevTool/components/Instance}/transformTree.ts +375 -375
  68. package/dist/v3/{Instance → DevTool/components/Instance}/transformTreeCtx.ts +268 -268
  69. package/dist/v3/{Instance → DevTool/components/Instance}/typing.d.ts +43 -43
  70. package/dist/v3/{InstanceDetail → DevTool/components/InstanceDetail}/index.vue +485 -485
  71. package/dist/v3/{JsonDetail → DevTool/components/JsonDetail}/index.vue +70 -70
  72. package/dist/v3/{NFCList → DevTool/components/NFCList}/NFCItem.vue +112 -113
  73. package/dist/v3/{NFCList → DevTool/components/NFCList}/NFCTool.vue +454 -478
  74. package/dist/v3/{NFCList → DevTool/components/NFCList}/const.ts +56 -56
  75. package/dist/v3/{NFCList → DevTool/components/NFCList}/index.vue +94 -98
  76. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/InterceptConfig.vue +624 -608
  77. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/InterceptItem.vue +140 -140
  78. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/NetworkDetail.vue +287 -296
  79. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/NetworkIntercept.vue +88 -93
  80. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/NetworkItem.vue +163 -167
  81. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/NetworkSend.vue +589 -556
  82. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/const.ts +4 -4
  83. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/hooks/useNetworkForm.ts +86 -86
  84. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/index.vue +160 -160
  85. package/dist/v3/{NetworkList → DevTool/components/NetworkList}/utils.ts +101 -101
  86. package/dist/v3/{Performance → DevTool/components/Performance}/index.vue +498 -495
  87. package/dist/v3/{Performance → DevTool/components/Performance}/modules/PerformanceMetrics.vue +153 -153
  88. package/dist/v3/{Performance → DevTool/components/Performance}/modules/PerformanceWidget.vue +12 -9
  89. package/dist/v3/{Performance → DevTool/components/Performance}/modules/usePerformanceChart.ts +460 -460
  90. package/dist/v3/{Performance → DevTool/components/Performance}/modules/usePerformanceData.ts +258 -258
  91. package/dist/v3/{PiniaList → DevTool/components/PiniaList}/index.vue +93 -94
  92. package/dist/v3/{RouteList → DevTool/components/RouteList}/index.vue +21 -24
  93. package/dist/v3/{RunJS → DevTool/components/RunJS}/index.vue +148 -148
  94. package/dist/v3/{ScanCodeList → DevTool/components/ScanCodeList}/ScanCodeItem.vue +97 -98
  95. package/dist/v3/{ScanCodeList → DevTool/components/ScanCodeList}/index.vue +100 -104
  96. package/dist/v3/{SettingButton → DevTool/components/SettingButton}/index.vue +45 -45
  97. package/dist/v3/{SettingList → DevTool/components/SettingList}/index.vue +218 -150
  98. package/dist/v3/DevTool/components/SettingList/modules/SettingBarrage.vue +304 -0
  99. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingDevTool.vue +212 -208
  100. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingInfo.vue +157 -119
  101. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingLanguage.vue +74 -74
  102. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingLog.vue +230 -230
  103. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingNetwork.vue +3 -3
  104. package/dist/v3/{SettingList → DevTool/components/SettingList}/modules/SettingTheme.vue +37 -7
  105. package/dist/v3/{SettingList → DevTool/components/SettingList}/typing.d.ts +2 -2
  106. package/dist/v3/{SourceCode → DevTool/components/SourceCode}/Line.vue +127 -116
  107. package/dist/v3/{SourceCode → DevTool/components/SourceCode}/index.vue +8 -8
  108. package/dist/v3/{SourceCode → DevTool/components/SourceCode}/parseCode.ts +609 -701
  109. package/dist/v3/{StorageList → DevTool/components/StorageList}/index.vue +174 -174
  110. package/dist/v3/{TransferList → DevTool/components/TransferList}/TransferDetail.vue +268 -268
  111. package/dist/v3/{TransferList → DevTool/components/TransferList}/TransferItem.vue +4 -4
  112. package/dist/v3/{TransferList → DevTool/components/TransferList}/index.vue +8 -8
  113. package/dist/v3/{UniEvent → DevTool/components/UniEvent}/UniEventItem.vue +6 -7
  114. package/dist/v3/{UniEvent → DevTool/components/UniEvent}/index.vue +6 -6
  115. package/dist/v3/{VuexList → DevTool/components/VuexList}/index.vue +84 -84
  116. package/dist/v3/{WebSocket → DevTool/components/WebSocket}/WebSocketDetail.vue +8 -8
  117. package/dist/v3/{WebSocket → DevTool/components/WebSocket}/WebSocketItem.vue +4 -4
  118. package/dist/v3/{WebSocket → DevTool/components/WebSocket}/index.vue +8 -8
  119. package/dist/v3/DevTool/index.vue +179 -5
  120. package/dist/v3/{AppTransition → components/AppTransition}/index.vue +176 -170
  121. package/dist/v3/{AutoSizer → components/AutoSizer}/index.vue +192 -192
  122. package/dist/v3/{AutoSizer → components/AutoSizer}/index1.vue +184 -184
  123. package/dist/v3/{AutoSizer → components/AutoSizer}/utils.ts +49 -49
  124. package/dist/v3/components/Barrage/BarrageItem.vue +137 -0
  125. package/dist/v3/components/Barrage/index.vue +202 -0
  126. package/dist/v3/{CircularButton → components/CircularButton}/index.vue +84 -84
  127. package/dist/v3/{CustomSwiper → components/CustomSwiper}/CustomSwiperItem.vue +49 -49
  128. package/dist/v3/{CustomSwiper → components/CustomSwiper}/index.vue +104 -104
  129. package/dist/v3/{DraggableContainer → components/DraggableContainer}/index.vue +1 -1
  130. package/dist/v3/{Empty → components/Empty}/index.vue +29 -29
  131. package/dist/v3/{FilterInput → components/FilterInput}/index.vue +1 -1
  132. package/dist/v3/{FilterSelect → components/FilterSelect}/index.vue +179 -179
  133. package/dist/v3/{JsonPretty → components/JsonPretty}/components/Brackets/index.vue +27 -27
  134. package/dist/v3/{JsonPretty → components/JsonPretty}/components/Carets/index.vue +59 -59
  135. package/dist/v3/{JsonPretty → components/JsonPretty}/components/CheckController/index.vue +136 -136
  136. package/dist/v3/{JsonPretty → components/JsonPretty}/components/TreeNode/index.vue +387 -381
  137. package/dist/v3/{JsonPretty → components/JsonPretty}/hooks/useClipboard.ts +21 -21
  138. package/dist/v3/{JsonPretty → components/JsonPretty}/hooks/useError.ts +21 -21
  139. package/dist/v3/{JsonPretty → components/JsonPretty}/index.vue +16 -13
  140. package/dist/v3/{JsonPretty → components/JsonPretty}/type.ts +127 -126
  141. package/dist/v3/{JsonPretty → components/JsonPretty}/utils/index.ts +169 -169
  142. package/dist/v3/{MovableContainer → components/MovableContainer}/index.vue +1 -1
  143. package/dist/v3/{Pick → components/Pick}/index.vue +322 -322
  144. package/dist/v3/{Tabs → components/Tabs}/index.vue +30 -4
  145. package/dist/v3/{Tag → components/Tag}/index.vue +113 -113
  146. package/dist/v3/{VirtualList → components/VirtualList}/AutoSize.vue +40 -40
  147. package/dist/v3/{VirtualList → components/VirtualList}/index.vue +416 -412
  148. package/dist/v3/hooks/useBluetooth/index.ts +561 -0
  149. package/dist/v3/hooks/useContainerStyle.ts +153 -153
  150. package/dist/v3/hooks/useNFC/index.ts +107 -107
  151. package/dist/v3/hooks/useNFC/typing.d.ts +396 -396
  152. package/dist/v3/hooks/useNFC/useNFCAndroid.ts +966 -966
  153. package/dist/v3/hooks/useNFC/useNFCMpWeiXin.ts +812 -812
  154. package/dist/v3/hooks/useNFC/utils.ts +754 -754
  155. package/dist/v3/hooks/useRequest/index.ts +586 -573
  156. package/dist/v3/hooks/useRequest/utils.ts +267 -267
  157. package/dist/v3/hooks/useScanCode/index.ts +206 -206
  158. package/dist/v3/hooks/useWebsocket/README.md +79 -0
  159. package/dist/v3/hooks/useWebsocket/index.ts +253 -0
  160. package/dist/v3/styles/theme.css +17 -10
  161. package/dist/v3/styles/theme.ts +12 -12
  162. package/package.json +59 -64
  163. package/dist/plugins/uniParseStock/index.d.ts +0 -10
  164. package/dist/plugins/uniParseStock/index.d.ts.map +0 -1
  165. /package/dist/v3/{DevToolWindow → DevTool/components/DevToolWindow}/index.css +0 -0
  166. /package/dist/v3/{SettingList → DevTool/components/SettingList}/index.css +0 -0
  167. /package/dist/v3/{Empty → components/Empty}/empty.png +0 -0
  168. /package/dist/v3/{VirtualList → components/VirtualList}/readme.md +0 -0
@@ -1,573 +1,586 @@
1
- import { onMounted, ref, shallowReactive, watch, type Ref } from 'vue';
2
- import { debounce, throttle } from './utils';
3
-
4
- // 添加分页响应数据类型
5
- // type PaginationResponse<T = any> = {
6
- // list?: T[];
7
- // data?: T[];
8
- // total: number;
9
- // current: number;
10
- // pageSize: number;
11
- // };
12
-
13
- type Option<R, P> = {
14
- /** 是否需要uni.showLoading */
15
- useUniLoading?: boolean;
16
- /**
17
- * 每次 ready 从 false 变为 true 时, 都会自动发起请求
18
- * 为 false 时,请求永远都不会发出
19
- */
20
- ready?: boolean | Ref<boolean>;
21
- /** 立即执行 */
22
- manual?: boolean;
23
- /**
24
- * 默认参数
25
- * 分页参数在请放入 分页参数配置中
26
- */
27
- defaultParams?: P;
28
- /** 依赖刷新 */
29
- refreshDeps?: any[];
30
- /**
31
- * 延迟结束loading
32
- * 单位毫秒
33
- * 防止请求过快造成渲染闪烁
34
- */
35
- loadingDelay?: number;
36
- /**
37
- * 轮询间隔
38
- * 通过 run/runAsync 来启动轮询
39
- * 通过 cancel 取消轮询
40
- */
41
- pollingInterval?: number;
42
- /**
43
- * 轮询错误重试次数
44
- */
45
- pollingErrorRetryCount?: number;
46
- /**
47
- * 错误重试次数
48
- */
49
- errorRetryCount?: number;
50
- /**
51
- * 错误重试间隔
52
- */
53
- errorRetryDelay?: number;
54
- /**
55
- * 防抖等待时间
56
- */
57
- debounceWait?: number;
58
- /**
59
- * 在防抖开始前执行调用
60
- */
61
- debounceLeading?: boolean;
62
- /**
63
- * 在防抖结束后执行调用
64
- */
65
- debounceTrailing?: boolean;
66
- /**
67
- * 节流等待时间
68
- */
69
- throttleWait?: number;
70
- /**
71
- * 在节流开始前执行调用
72
- */
73
- throttleLeading?: boolean;
74
- /**
75
- * 在节流结束后执行调用
76
- */
77
- throttleTrailing?: boolean;
78
- /**
79
- * 使用分页
80
- */
81
- usePagination?: boolean;
82
- /**
83
- * 分页配置
84
- *
85
- */
86
- paginationConfig?: {
87
- /** 当前页码参数名,默认 'current' */
88
- currentKey?: string;
89
- /** 每页数量参数名,默认 'pageSize' */
90
- pageSizeKey?: string;
91
- /** 总数字段名,默认 'total' */
92
- totalKey?: string;
93
- /** 默认当前页,默认 1 */
94
- defaultCurrent?: number;
95
- /** 默认每页数量,默认 10 */
96
- defaultPageSize?: number;
97
- /** 列表字段名,默认 'list' */
98
- listKey?: string;
99
- };
100
- /** 请求前 */
101
- onBefore?: () => Promise<void> | void;
102
- /** 请求成功 */
103
- onSuccess?: (result: R | undefined, params?: P) => void;
104
- /** 请求失败 */
105
- onError?: (error: any) => void;
106
- /** 请求完成 */
107
- onFinally?: () => void;
108
- };
109
-
110
- export type Service<R, P extends any[]> = (...args: P) => Promise<R>;
111
-
112
- const useRequest = <R, P extends any[]>(
113
- service: Service<R, P>,
114
- option?: Option<R, P>,
115
- ) => {
116
- const loading = ref(false);
117
-
118
- const data = ref<R>();
119
-
120
- /**
121
- * 启用 usePagination 之后每页数据合并之后的结果
122
- * 为开启默认为 []
123
- * 只适合从第一页开始获取数据
124
- */
125
- const list = ref<R[]>([]);
126
-
127
- const pagination = shallowReactive({
128
- current: 1,
129
- pageSize: 10,
130
- total: 0,
131
- totalPage: 0,
132
- hasMore: true,
133
- // 分页操作方法
134
- setCurrent: (current: number) => {
135
- pagination.current = Math.max(1, current);
136
- refresh();
137
- },
138
- setPageSize: (pageSize: number) => {
139
- pagination.pageSize = pageSize;
140
- pagination.current = 1; // 重置到第一页
141
- refresh();
142
- },
143
- reset: () => {
144
- pagination.current = option?.paginationConfig?.defaultCurrent ?? 1;
145
- pagination.pageSize = option?.paginationConfig?.defaultPageSize ?? 10;
146
- refresh();
147
- },
148
- prev: () => {
149
- if (pagination.current > 1) {
150
- pagination.current--;
151
- refresh();
152
- }
153
- },
154
- next: () => {
155
- if (pagination.current < pagination.totalPage) {
156
- pagination.current++;
157
- refresh();
158
- }
159
- },
160
- change: (current: number, pageSize: number) => {
161
- pagination.current = current;
162
- pagination.pageSize = pageSize;
163
- refresh();
164
- },
165
- });
166
-
167
- /** 最后一次请求的参数 */
168
- let lastParams: P | undefined;
169
-
170
- let loadingTimer: any;
171
-
172
- let intervalTimer: any;
173
-
174
- let allowPolling = true;
175
-
176
- let pollingErrorCount = 0;
177
-
178
- let errorCount = 0;
179
-
180
- let intervalErrorRetry: ReturnType<typeof setTimeout> | undefined = undefined;
181
-
182
- /** 记录上次 ready 的状态 */
183
- let previousReady = false;
184
-
185
- /** 获取 ready 值 */
186
- const getReadyValue = (): boolean => {
187
- if (option?.ready === undefined) return true;
188
- return typeof option.ready === 'boolean'
189
- ? option.ready
190
- : option.ready.value;
191
- };
192
-
193
- /**
194
- *
195
- * @param params 请求参数
196
- */
197
- function run(...params: P) {
198
- if (getReadyValue()) {
199
- execServiceFunction(params)
200
- ?.catch((error) => {
201
- errorRetry(params);
202
- throw error;
203
- })
204
- ?.finally(() => {
205
- if (option?.pollingInterval && option.pollingInterval > 0) {
206
- startPolling(params);
207
- }
208
- });
209
- }
210
- }
211
-
212
- async function runAsync(...params: P) {
213
- // 只有在 ready 为 true 时才执行请求
214
- if (getReadyValue()) {
215
- try {
216
- const result = await execServiceFunction?.(params);
217
-
218
- return result;
219
- } catch (error) {
220
- errorRetry(params);
221
- throw error;
222
- } finally {
223
- if (option?.pollingInterval && option.pollingInterval > 0) {
224
- startPolling(params);
225
- }
226
- }
227
- }
228
- }
229
-
230
- /**
231
- * 刷新
232
- *
233
- */
234
- function refresh() {
235
- // 只有在 ready 为 true 时才执行请求
236
- if (getReadyValue()) {
237
- const fallbackParams: P = ((lastParams || option?.defaultParams) ??
238
- []) as P;
239
-
240
- execServiceFunction(fallbackParams);
241
- }
242
- }
243
-
244
- /**
245
- * 刷新异步
246
- *
247
- * @return {*}
248
- */
249
- function refreshAsync() {
250
- // 只有在 ready 为 true 时才执行请求
251
- if (getReadyValue()) {
252
- const fallbackParams: P = ((lastParams || option?.defaultParams) ??
253
- []) as P;
254
-
255
- return execServiceFunction(fallbackParams);
256
- }
257
- }
258
-
259
- async function execService(params: P) {
260
- // 只有在 ready 为 true 时才执行请求
261
- if (getReadyValue()) {
262
- try {
263
- loading.value = true;
264
-
265
- if (option?.useUniLoading) {
266
- uni.showLoading({
267
- title: '加载中...',
268
- mask: true,
269
- });
270
- }
271
-
272
- lastParams = params;
273
-
274
- await option?.onBefore?.();
275
-
276
- const result = await service(...params);
277
-
278
- data.value = result;
279
-
280
- // 如果启用了分页功能,处理分页数据
281
- if (option?.usePagination) {
282
- const config = option.paginationConfig || {};
283
- const currentKey = config.currentKey || 'current';
284
- const pageSizeKey = config.pageSizeKey || 'pageSize';
285
- const totalKey = config.totalKey || 'total';
286
- const listKey = config.listKey || 'list';
287
-
288
- // 检查结果是否为分页格式
289
- if (result && typeof result === 'object') {
290
- const paginationResult = result as any;
291
- pagination.current =
292
- paginationResult[currentKey] || pagination.current;
293
- pagination.pageSize =
294
- paginationResult[pageSizeKey] || pagination.pageSize;
295
- pagination.total = paginationResult[totalKey] || 0;
296
- pagination.totalPage = Math.ceil(
297
- pagination.total / pagination.pageSize,
298
- );
299
- pagination.hasMore = pagination.current < pagination.totalPage;
300
-
301
- // 获取列表数据
302
- const resultData =
303
- paginationResult[listKey] ||
304
- paginationResult.data ||
305
- paginationResult.list ||
306
- [];
307
- // 根据当前页码决定是否合并列表数据
308
- if (pagination.current === 1) {
309
- // 第一页时,替换列表
310
- list.value = [...resultData];
311
- } else {
312
- // 非第一页时,合并列表
313
- list.value = [...list.value, ...resultData];
314
- }
315
- } else {
316
- pagination.hasMore = false;
317
- }
318
- }
319
-
320
- option?.onSuccess?.(data.value, params);
321
-
322
- return data.value;
323
- } catch (error) {
324
- pollingErrorCount++;
325
- errorCount++;
326
- option?.onError?.(error);
327
- throw error;
328
- } finally {
329
- option?.onFinally?.();
330
-
331
- // 结束loading
332
- if (option?.useUniLoading) {
333
- // 延迟结束loading
334
- if (option?.loadingDelay && option.loadingDelay > 0) {
335
- clearTimeout(loadingTimer);
336
-
337
- loadingTimer = setTimeout(() => {
338
- loading.value = false;
339
-
340
- uni.hideLoading();
341
- }, option.loadingDelay);
342
- } else {
343
- loading.value = false;
344
-
345
- uni.hideLoading();
346
- }
347
- }
348
- }
349
- }
350
- }
351
-
352
- const execServiceDebounce = debounce(execService, option?.debounceWait ?? 0, {
353
- leading: option?.debounceLeading,
354
- trailing: option?.debounceTrailing,
355
- });
356
-
357
- const execServiceThrottle = throttle(execService, option?.throttleWait ?? 0, {
358
- leading: option?.throttleLeading,
359
- trailing: option?.throttleTrailing,
360
- });
361
-
362
- function execServiceFunction(params: P) {
363
- if (option?.usePagination) {
364
- const config = option.paginationConfig || {};
365
- const currentKey = config.currentKey || 'current';
366
- const pageSizeKey = config.pageSizeKey || 'pageSize';
367
-
368
- // 将分页参数注入到请求参数中
369
- const paramsWithPagination = [...params] as any[];
370
-
371
- // 如果参数是对象,添加分页字段
372
- if (
373
- paramsWithPagination.length > 0 &&
374
- typeof paramsWithPagination[0] === 'object' &&
375
- paramsWithPagination[0] !== null
376
- ) {
377
- paramsWithPagination[0] = {
378
- ...paramsWithPagination[0],
379
- [currentKey]: pagination.current,
380
- [pageSizeKey]: pagination.pageSize,
381
- };
382
- } else {
383
- // 如果没有参数或参数不是对象,创建一个包含分页信息的对象
384
- paramsWithPagination.unshift({
385
- [currentKey]: pagination.current,
386
- [pageSizeKey]: pagination.pageSize,
387
- });
388
- }
389
-
390
- if (option?.debounceWait) {
391
- return execServiceDebounce(paramsWithPagination as P);
392
- } else if (option?.throttleWait) {
393
- return execServiceThrottle(paramsWithPagination as P);
394
- } else {
395
- return execService(paramsWithPagination as P);
396
- }
397
- } else {
398
- if (option?.debounceWait) {
399
- return execServiceDebounce(params);
400
- } else if (option?.throttleWait) {
401
- return execServiceThrottle(params);
402
- } else {
403
- return execService(params);
404
- }
405
- }
406
- }
407
-
408
- /**
409
- * 开启轮询
410
- *
411
- * @param {P} params
412
- */
413
- function startPolling(params: P) {
414
- cancel();
415
-
416
- allowPolling = true;
417
-
418
- if (!getReadyValue()) return;
419
-
420
- // 使用递归函数实现轮询,确保请求完成后才开始计时下一次请求
421
- const poll = async () => {
422
- if (!allowPolling) return;
423
- // 检查 ready 状态
424
-
425
- try {
426
- await execService(params);
427
-
428
- // 检查错误重试次数限制
429
- if (
430
- option?.pollingErrorRetryCount &&
431
- pollingErrorCount >= option.pollingErrorRetryCount
432
- ) {
433
- cancel();
434
- return;
435
- }
436
-
437
- // 如果仍然允许轮询,则设置定时器等待下次轮询
438
- if (allowPolling) {
439
- intervalTimer = setTimeout(poll, option?.pollingInterval);
440
- }
441
- } catch (_error) {
442
- // execService 内部已经处理了错误,这里只需要确保继续轮询或停止
443
- if (
444
- option?.pollingErrorRetryCount &&
445
- pollingErrorCount >= option.pollingErrorRetryCount
446
- ) {
447
- cancel();
448
- return;
449
- }
450
-
451
- // 如果仍然允许轮询,则设置定时器等待下次轮询
452
- if (allowPolling) {
453
- intervalTimer = setTimeout(poll, option?.pollingInterval);
454
- }
455
- }
456
- };
457
-
458
- // 先等待轮询间隔时间,然后再开始执行请求
459
- intervalTimer = setTimeout(() => {
460
- // 开始轮询
461
- poll();
462
- }, option?.pollingInterval);
463
- }
464
-
465
- /** 取消轮询 */
466
- function cancel() {
467
- allowPolling = false;
468
- pollingErrorCount = 0;
469
- errorCount = 0;
470
- clearInterval(intervalTimer);
471
- clearInterval(intervalErrorRetry);
472
- }
473
-
474
- /**
475
- * 错误重试
476
- *
477
- * @param {P} params
478
- * @return {*}
479
- */
480
- function errorRetry(params: P) {
481
- // 存在则不进入错误重试
482
- if (option?.pollingErrorRetryCount || option?.pollingInterval) return;
483
- // 不存在 或者 次数小于 0 不进入错误重试
484
- if (!option?.errorRetryCount || option.errorRetryCount <= 0) return;
485
-
486
- if (!getReadyValue()) return;
487
-
488
- const poll = async () => {
489
- try {
490
- await execService(params);
491
- cancel();
492
- } catch (_error) {
493
- if (option.errorRetryCount && option.errorRetryCount < errorCount) {
494
- cancel();
495
- return;
496
- }
497
- intervalErrorRetry = setTimeout(poll, option?.errorRetryDelay ?? 0);
498
- }
499
- };
500
-
501
- intervalErrorRetry = setTimeout(poll, option?.errorRetryDelay ?? 0);
502
- }
503
-
504
- function setData(value: R) {
505
- data.value = value;
506
- }
507
-
508
- function setLoading(value: boolean) {
509
- loading.value = value;
510
- }
511
-
512
- onMounted(() => {
513
- // 记录初始 ready 状态
514
- previousReady = getReadyValue();
515
-
516
- // 初始化分页配置
517
- if (option?.usePagination) {
518
- const config = option.paginationConfig || {};
519
- pagination.current = config.defaultCurrent ?? 1;
520
- pagination.pageSize = config.defaultPageSize ?? 10;
521
- }
522
-
523
- if (!option?.manual && option?.ready !== false) {
524
- const defaultParams = (option?.defaultParams || []) as P;
525
- run(...defaultParams);
526
- }
527
- });
528
-
529
- // 监听 ready 参数变化
530
- watch(
531
- () => getReadyValue(),
532
- (currentReady) => {
533
- // 只有当 ready false 变为 true 时才执行请求
534
- if (currentReady && !previousReady) {
535
- const params = (lastParams || option?.defaultParams || []) as P;
536
- // run(...params);
537
- execService(params).catch(() => {
538
- errorRetry(params);
539
- });
540
- } else {
541
- cancel();
542
- }
543
- // 更新 previousReady 状态
544
- previousReady = !!currentReady;
545
- },
546
- );
547
-
548
- watch(
549
- () => option?.refreshDeps,
550
- () => {
551
- refresh();
552
- },
553
- {
554
- deep: true,
555
- },
556
- );
557
-
558
- return {
559
- data,
560
- setData,
561
- loading,
562
- setLoading,
563
- run,
564
- runAsync,
565
- refresh,
566
- refreshAsync,
567
- cancel,
568
- pagination: option?.usePagination ? pagination : undefined,
569
- list,
570
- };
571
- };
572
-
573
- export default useRequest;
1
+ import {
2
+ onMounted,
3
+ onUnmounted,
4
+ ref,
5
+ shallowReactive,
6
+ watch,
7
+ type Ref,
8
+ } from 'vue';
9
+ import { debounce, throttle } from './utils';
10
+
11
+ // 添加分页响应数据类型
12
+ // type PaginationResponse<T = any> = {
13
+ // list?: T[];
14
+ // data?: T[];
15
+ // total: number;
16
+ // current: number;
17
+ // pageSize: number;
18
+ // };
19
+
20
+ type Option<R, P> = {
21
+ /** 是否需要uni.showLoading */
22
+ useUniLoading?: boolean;
23
+ /**
24
+ * 每次 ready 从 false 变为 true 时, 都会自动发起请求
25
+ * false 时,请求永远都不会发出
26
+ */
27
+ ready?: boolean | Ref<boolean>;
28
+ /** 立即执行 */
29
+ manual?: boolean;
30
+ /**
31
+ * 默认参数
32
+ * 分页参数在请放入 分页参数配置中
33
+ */
34
+ defaultParams?: P;
35
+ /** 依赖刷新 */
36
+ refreshDeps?: any[];
37
+ /**
38
+ * 延迟结束loading
39
+ * 单位毫秒
40
+ * 防止请求过快造成渲染闪烁
41
+ */
42
+ loadingDelay?: number;
43
+ /**
44
+ * 轮询间隔
45
+ * 通过 run/runAsync 来启动轮询
46
+ * 通过 cancel 取消轮询
47
+ */
48
+ pollingInterval?: number;
49
+ /**
50
+ * 轮询错误重试次数
51
+ */
52
+ pollingErrorRetryCount?: number;
53
+ /**
54
+ * 错误重试次数
55
+ */
56
+ errorRetryCount?: number;
57
+ /**
58
+ * 错误重试间隔
59
+ */
60
+ errorRetryDelay?: number;
61
+ /**
62
+ * 防抖等待时间
63
+ */
64
+ debounceWait?: number;
65
+ /**
66
+ * 在防抖开始前执行调用
67
+ */
68
+ debounceLeading?: boolean;
69
+ /**
70
+ * 在防抖结束后执行调用
71
+ */
72
+ debounceTrailing?: boolean;
73
+ /**
74
+ * 节流等待时间
75
+ */
76
+ throttleWait?: number;
77
+ /**
78
+ * 在节流开始前执行调用
79
+ */
80
+ throttleLeading?: boolean;
81
+ /**
82
+ * 在节流结束后执行调用
83
+ */
84
+ throttleTrailing?: boolean;
85
+ /**
86
+ * 使用分页
87
+ */
88
+ usePagination?: boolean;
89
+ /**
90
+ * 分页配置
91
+ *
92
+ */
93
+ paginationConfig?: {
94
+ /** 当前页码参数名,默认 'current' */
95
+ currentKey?: string;
96
+ /** 每页数量参数名,默认 'pageSize' */
97
+ pageSizeKey?: string;
98
+ /** 总数字段名,默认 'total' */
99
+ totalKey?: string;
100
+ /** 默认当前页,默认 1 */
101
+ defaultCurrent?: number;
102
+ /** 默认每页数量,默认 10 */
103
+ defaultPageSize?: number;
104
+ /** 列表字段名,默认 'list' */
105
+ listKey?: string;
106
+ };
107
+ /** 请求前 */
108
+ onBefore?: () => Promise<void> | void;
109
+ /** 请求成功 */
110
+ onSuccess?: (result: R | undefined, params?: P) => void;
111
+ /** 请求失败 */
112
+ onError?: (error: any) => void;
113
+ /** 请求完成 */
114
+ onFinally?: () => void;
115
+ };
116
+
117
+ export type Service<R, P extends any[]> = (...args: P) => Promise<R>;
118
+
119
+ const useRequest = <R, P extends any[]>(
120
+ service: Service<R, P>,
121
+ option?: Option<R, P>,
122
+ ) => {
123
+ const loading = ref(false);
124
+
125
+ const data = ref<R>();
126
+
127
+ /**
128
+ * 启用 usePagination 之后每页数据合并之后的结果
129
+ * 不开启默认为 []
130
+ * 只适合从第一页开始获取数据
131
+ */
132
+ const list = ref<any[]>([]);
133
+
134
+ const pagination = shallowReactive({
135
+ current: 1,
136
+ pageSize: 10,
137
+ total: 0,
138
+ totalPage: 0,
139
+ hasMore: true,
140
+ // 分页操作方法
141
+ setCurrent: (current: number) => {
142
+ pagination.current = Math.max(1, current);
143
+ refresh();
144
+ },
145
+ setPageSize: (pageSize: number) => {
146
+ pagination.pageSize = pageSize;
147
+ pagination.current = 1; // 重置到第一页
148
+ refresh();
149
+ },
150
+ reset: () => {
151
+ pagination.current = option?.paginationConfig?.defaultCurrent ?? 1;
152
+ pagination.pageSize = option?.paginationConfig?.defaultPageSize ?? 10;
153
+ refresh();
154
+ },
155
+ prev: () => {
156
+ if (pagination.current > 1) {
157
+ pagination.current--;
158
+ refresh();
159
+ }
160
+ },
161
+ next: () => {
162
+ if (pagination.current < pagination.totalPage) {
163
+ pagination.current++;
164
+ refresh();
165
+ }
166
+ },
167
+ change: (current: number, pageSize: number) => {
168
+ pagination.current = current;
169
+ pagination.pageSize = pageSize;
170
+ refresh();
171
+ },
172
+ });
173
+
174
+ /** 最后一次请求的参数 */
175
+ let lastParams: P | undefined;
176
+
177
+ let loadingTimer: any;
178
+
179
+ let intervalTimer: any;
180
+
181
+ let allowPolling = true;
182
+
183
+ let pollingErrorCount = 0;
184
+
185
+ let errorCount = 0;
186
+
187
+ let intervalErrorRetry: ReturnType<typeof setTimeout> | undefined = undefined;
188
+
189
+ /** 记录上次 ready 的状态 */
190
+ let previousReady = false;
191
+
192
+ /** 获取 ready 值 */
193
+ const getReadyValue = (): boolean => {
194
+ if (option?.ready === undefined) return true;
195
+ return typeof option.ready === 'boolean'
196
+ ? option.ready
197
+ : option.ready.value;
198
+ };
199
+
200
+ /**
201
+ *
202
+ * @param params 请求参数
203
+ */
204
+ function run(...params: P) {
205
+ if (getReadyValue()) {
206
+ execServiceFunction(params)
207
+ ?.catch((error) => {
208
+ errorRetry(params);
209
+ throw error;
210
+ })
211
+ ?.finally(() => {
212
+ if (option?.pollingInterval && option.pollingInterval > 0) {
213
+ startPolling(params);
214
+ }
215
+ });
216
+ }
217
+ }
218
+
219
+ async function runAsync(...params: P) {
220
+ // 只有在 ready 为 true 时才执行请求
221
+ if (getReadyValue()) {
222
+ try {
223
+ const result = await execServiceFunction?.(params);
224
+
225
+ return result;
226
+ } catch (error) {
227
+ errorRetry(params);
228
+ throw error;
229
+ } finally {
230
+ if (option?.pollingInterval && option.pollingInterval > 0) {
231
+ startPolling(params);
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ /**
238
+ * 刷新
239
+ *
240
+ */
241
+ function refresh() {
242
+ // 只有在 ready 为 true 时才执行请求
243
+ if (getReadyValue()) {
244
+ const fallbackParams: P = ((lastParams || option?.defaultParams) ??
245
+ []) as P;
246
+
247
+ execServiceFunction(fallbackParams);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * 刷新异步
253
+ *
254
+ * @return {*}
255
+ */
256
+ function refreshAsync() {
257
+ // 只有在 ready 为 true 时才执行请求
258
+ if (getReadyValue()) {
259
+ const fallbackParams: P = ((lastParams || option?.defaultParams) ??
260
+ []) as P;
261
+
262
+ return execServiceFunction(fallbackParams);
263
+ }
264
+ }
265
+
266
+ async function execService(params: P) {
267
+ // 只有在 ready 为 true 时才执行请求
268
+ if (getReadyValue()) {
269
+ try {
270
+ loading.value = true;
271
+
272
+ if (option?.useUniLoading) {
273
+ uni.showLoading({
274
+ title: '加载中...',
275
+ mask: true,
276
+ });
277
+ }
278
+
279
+ lastParams = params;
280
+
281
+ await option?.onBefore?.();
282
+
283
+ const result = await service(...params);
284
+
285
+ data.value = result;
286
+
287
+ // 如果启用了分页功能,处理分页数据
288
+ if (option?.usePagination) {
289
+ const config = option.paginationConfig || {};
290
+ const currentKey = config.currentKey || 'current';
291
+ const pageSizeKey = config.pageSizeKey || 'pageSize';
292
+ const totalKey = config.totalKey || 'total';
293
+ const listKey = config.listKey || 'list';
294
+
295
+ // 检查结果是否为分页格式
296
+ if (result && typeof result === 'object') {
297
+ const paginationResult = result as any;
298
+ pagination.current =
299
+ paginationResult[currentKey] || pagination.current;
300
+ pagination.pageSize =
301
+ paginationResult[pageSizeKey] || pagination.pageSize;
302
+ pagination.total = paginationResult[totalKey] || 0;
303
+ pagination.totalPage = Math.ceil(
304
+ pagination.total / pagination.pageSize,
305
+ );
306
+ pagination.hasMore = pagination.current < pagination.totalPage;
307
+
308
+ // 获取列表数据
309
+ const resultData =
310
+ paginationResult[listKey] ||
311
+ paginationResult.data ||
312
+ paginationResult.list ||
313
+ [];
314
+ // 根据当前页码决定是否合并列表数据
315
+ if (pagination.current === 1) {
316
+ // 第一页时,替换列表
317
+ list.value = [...resultData];
318
+ } else {
319
+ // 非第一页时,合并列表
320
+ list.value = [...list.value, ...resultData];
321
+ }
322
+ } else {
323
+ pagination.hasMore = false;
324
+ }
325
+ }
326
+
327
+ option?.onSuccess?.(data.value, params);
328
+
329
+ return data.value;
330
+ } catch (error) {
331
+ pollingErrorCount++;
332
+ errorCount++;
333
+ option?.onError?.(error);
334
+ throw error;
335
+ } finally {
336
+ option?.onFinally?.();
337
+
338
+ const finishLoading = () => {
339
+ loading.value = false;
340
+ if (option?.useUniLoading) {
341
+ uni.hideLoading();
342
+ }
343
+ };
344
+
345
+ // 结束loading
346
+ if (
347
+ option?.useUniLoading &&
348
+ option?.loadingDelay &&
349
+ option.loadingDelay > 0
350
+ ) {
351
+ clearTimeout(loadingTimer);
352
+ loadingTimer = setTimeout(finishLoading, option.loadingDelay);
353
+ } else {
354
+ finishLoading();
355
+ }
356
+ }
357
+ }
358
+ }
359
+
360
+ const execServiceDebounce = debounce(execService, option?.debounceWait ?? 0, {
361
+ leading: option?.debounceLeading,
362
+ trailing: option?.debounceTrailing,
363
+ });
364
+
365
+ const execServiceThrottle = throttle(execService, option?.throttleWait ?? 0, {
366
+ leading: option?.throttleLeading,
367
+ trailing: option?.throttleTrailing,
368
+ });
369
+
370
+ function execServiceFunction(params: P) {
371
+ if (option?.usePagination) {
372
+ const config = option.paginationConfig || {};
373
+ const currentKey = config.currentKey || 'current';
374
+ const pageSizeKey = config.pageSizeKey || 'pageSize';
375
+
376
+ // 将分页参数注入到请求参数中
377
+ const paramsWithPagination = [...params] as any[];
378
+
379
+ // 如果参数是对象,添加分页字段
380
+ if (
381
+ paramsWithPagination.length > 0 &&
382
+ typeof paramsWithPagination[0] === 'object' &&
383
+ paramsWithPagination[0] !== null
384
+ ) {
385
+ paramsWithPagination[0] = {
386
+ ...paramsWithPagination[0],
387
+ [currentKey]: pagination.current,
388
+ [pageSizeKey]: pagination.pageSize,
389
+ };
390
+ } else {
391
+ // 如果没有参数或参数不是对象,创建一个包含分页信息的对象
392
+ paramsWithPagination.unshift({
393
+ [currentKey]: pagination.current,
394
+ [pageSizeKey]: pagination.pageSize,
395
+ });
396
+ }
397
+
398
+ if (option?.debounceWait) {
399
+ return execServiceDebounce(paramsWithPagination as P);
400
+ } else if (option?.throttleWait) {
401
+ return execServiceThrottle(paramsWithPagination as P);
402
+ } else {
403
+ return execService(paramsWithPagination as P);
404
+ }
405
+ } else {
406
+ if (option?.debounceWait) {
407
+ return execServiceDebounce(params);
408
+ } else if (option?.throttleWait) {
409
+ return execServiceThrottle(params);
410
+ } else {
411
+ return execService(params);
412
+ }
413
+ }
414
+ }
415
+
416
+ /**
417
+ * 开启轮询
418
+ *
419
+ * @param {P} params
420
+ */
421
+ function startPolling(params: P) {
422
+ cancel();
423
+
424
+ allowPolling = true;
425
+
426
+ if (!getReadyValue()) return;
427
+
428
+ // 使用递归函数实现轮询,确保请求完成后才开始计时下一次请求
429
+ const poll = async () => {
430
+ if (!allowPolling) return;
431
+ // 检查 ready 状态
432
+
433
+ try {
434
+ await execService(params);
435
+
436
+ // 检查错误重试次数限制
437
+ if (
438
+ option?.pollingErrorRetryCount &&
439
+ pollingErrorCount >= option.pollingErrorRetryCount
440
+ ) {
441
+ cancel();
442
+ return;
443
+ }
444
+
445
+ // 如果仍然允许轮询,则设置定时器等待下次轮询
446
+ if (allowPolling) {
447
+ intervalTimer = setTimeout(poll, option?.pollingInterval);
448
+ }
449
+ } catch (_error) {
450
+ // execService 内部已经处理了错误,这里只需要确保继续轮询或停止
451
+ if (
452
+ option?.pollingErrorRetryCount &&
453
+ pollingErrorCount >= option.pollingErrorRetryCount
454
+ ) {
455
+ cancel();
456
+ return;
457
+ }
458
+
459
+ // 如果仍然允许轮询,则设置定时器等待下次轮询
460
+ if (allowPolling) {
461
+ intervalTimer = setTimeout(poll, option?.pollingInterval);
462
+ }
463
+ }
464
+ };
465
+
466
+ // 先等待轮询间隔时间,然后再开始执行请求
467
+ intervalTimer = setTimeout(() => {
468
+ // 开始轮询
469
+ poll();
470
+ }, option?.pollingInterval);
471
+ }
472
+
473
+ /** 取消轮询/重试 */
474
+ function cancel() {
475
+ allowPolling = false;
476
+ pollingErrorCount = 0;
477
+ errorCount = 0;
478
+ clearTimeout(intervalTimer);
479
+ clearTimeout(intervalErrorRetry);
480
+ clearTimeout(loadingTimer);
481
+ }
482
+
483
+ /**
484
+ * 错误重试
485
+ *
486
+ * @param {P} params
487
+ * @return {*}
488
+ */
489
+ function errorRetry(params: P) {
490
+ // 存在则不进入错误重试
491
+ if (option?.pollingErrorRetryCount || option?.pollingInterval) return;
492
+ // 不存在 或者 次数小于 0 不进入错误重试
493
+ if (!option?.errorRetryCount || option.errorRetryCount <= 0) return;
494
+
495
+ if (!getReadyValue()) return;
496
+
497
+ const poll = async () => {
498
+ try {
499
+ await execService(params);
500
+ cancel();
501
+ } catch (_error) {
502
+ if (option.errorRetryCount && option.errorRetryCount < errorCount) {
503
+ cancel();
504
+ return;
505
+ }
506
+ intervalErrorRetry = setTimeout(poll, option?.errorRetryDelay ?? 0);
507
+ }
508
+ };
509
+
510
+ intervalErrorRetry = setTimeout(poll, option?.errorRetryDelay ?? 0);
511
+ }
512
+
513
+ function setData(value: R) {
514
+ data.value = value;
515
+ }
516
+
517
+ function setLoading(value: boolean) {
518
+ loading.value = value;
519
+ }
520
+
521
+ onMounted(() => {
522
+ // 记录初始 ready 状态
523
+ previousReady = getReadyValue();
524
+
525
+ // 初始化分页配置
526
+ if (option?.usePagination) {
527
+ const config = option.paginationConfig || {};
528
+ pagination.current = config.defaultCurrent ?? 1;
529
+ pagination.pageSize = config.defaultPageSize ?? 10;
530
+ }
531
+
532
+ if (!option?.manual && option?.ready !== false) {
533
+ const defaultParams = (option?.defaultParams || []) as P;
534
+ run(...defaultParams);
535
+ }
536
+ });
537
+
538
+ onUnmounted(() => {
539
+ cancel();
540
+ });
541
+
542
+ // 监听 ready 参数变化
543
+ watch(
544
+ () => getReadyValue(),
545
+ (currentReady) => {
546
+ // 只有当 ready 从 false 变为 true 时才执行请求
547
+ if (currentReady && !previousReady) {
548
+ const params = (lastParams || option?.defaultParams || []) as P;
549
+ // run(...params);
550
+ execService(params).catch(() => {
551
+ errorRetry(params);
552
+ });
553
+ } else {
554
+ cancel();
555
+ }
556
+ // 更新 previousReady 状态
557
+ previousReady = !!currentReady;
558
+ },
559
+ );
560
+
561
+ watch(
562
+ () => option?.refreshDeps,
563
+ () => {
564
+ refresh();
565
+ },
566
+ {
567
+ deep: true,
568
+ },
569
+ );
570
+
571
+ return {
572
+ data,
573
+ setData,
574
+ loading,
575
+ setLoading,
576
+ run,
577
+ runAsync,
578
+ refresh,
579
+ refreshAsync,
580
+ cancel,
581
+ pagination: option?.usePagination ? pagination : undefined,
582
+ list,
583
+ };
584
+ };
585
+
586
+ export default useRequest;