@hlw-uni/mp-vue 2.1.52 → 2.1.55

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 (81) hide show
  1. package/dist/app.d.ts +2 -20
  2. package/dist/composables/ad/index.d.ts +11 -73
  3. package/dist/composables/device/index.d.ts +5 -70
  4. package/dist/composables/index.d.ts +6 -14
  5. package/dist/composables/navigator/index.d.ts +15 -39
  6. package/dist/composables/request/client.d.ts +21 -0
  7. package/dist/composables/request/index.d.ts +6 -0
  8. package/dist/composables/request/service.d.ts +30 -0
  9. package/dist/composables/{http → request}/types.d.ts +0 -3
  10. package/dist/composables/share/index.d.ts +7 -66
  11. package/dist/composables/utils/index.d.ts +25 -32
  12. package/dist/hlw.d.ts +2 -4
  13. package/dist/index.d.ts +2 -3
  14. package/dist/index.js +614 -1253
  15. package/dist/index.mjs +613 -1252
  16. package/package.json +2 -1
  17. package/src/app.ts +3 -143
  18. package/src/components/hlw-ad/index.vue +6 -5
  19. package/src/components/hlw-page/index.vue +1 -1
  20. package/src/composables/ad/README.md +58 -0
  21. package/src/composables/ad/index.ts +117 -376
  22. package/src/composables/device/README.md +50 -0
  23. package/src/composables/device/index.ts +110 -83
  24. package/src/composables/index.ts +10 -39
  25. package/src/composables/msg/README.md +79 -0
  26. package/src/composables/navigator/README.md +71 -0
  27. package/src/composables/navigator/index.ts +77 -77
  28. package/src/composables/refs/README.md +40 -0
  29. package/src/composables/request/README.md +124 -0
  30. package/src/composables/{http → request}/adapters/oss.ts +1 -0
  31. package/src/composables/request/client.ts +204 -0
  32. package/src/composables/request/index.ts +15 -0
  33. package/src/composables/request/service.ts +54 -0
  34. package/src/composables/{http → request}/types.ts +0 -4
  35. package/src/composables/share/README.md +53 -0
  36. package/src/composables/share/index.ts +64 -168
  37. package/src/composables/theme/README.md +131 -0
  38. package/src/composables/theme/index.ts +4 -2
  39. package/src/composables/theme/palette.ts +22 -4
  40. package/src/composables/utils/README.md +81 -0
  41. package/src/composables/utils/index.ts +131 -95
  42. package/src/hlw.ts +6 -14
  43. package/src/index.ts +2 -3
  44. package/dist/composables/_internal/unwrap.d.ts +0 -15
  45. package/dist/composables/algo/index.d.ts +0 -7
  46. package/dist/composables/algo/uuid.d.ts +0 -17
  47. package/dist/composables/color/index.d.ts +0 -8
  48. package/dist/composables/contact/index.d.ts +0 -32
  49. package/dist/composables/format/index.d.ts +0 -9
  50. package/dist/composables/http/client.d.ts +0 -66
  51. package/dist/composables/http/index.d.ts +0 -8
  52. package/dist/composables/loading/index.d.ts +0 -7
  53. package/dist/composables/page-meta/index.d.ts +0 -18
  54. package/dist/composables/storage/index.d.ts +0 -16
  55. package/dist/composables/validate/index.d.ts +0 -12
  56. package/dist/error.d.ts +0 -1
  57. package/src/composables/_internal/unwrap.ts +0 -19
  58. package/src/composables/algo/index.ts +0 -7
  59. package/src/composables/algo/uuid.ts +0 -27
  60. package/src/composables/color/index.ts +0 -44
  61. package/src/composables/contact/index.ts +0 -92
  62. package/src/composables/format/index.ts +0 -48
  63. package/src/composables/http/client.ts +0 -237
  64. package/src/composables/http/index.ts +0 -8
  65. package/src/composables/http/useRequest.ts +0 -107
  66. package/src/composables/loading/index.ts +0 -23
  67. package/src/composables/page-meta/index.ts +0 -49
  68. package/src/composables/storage/index.ts +0 -76
  69. package/src/composables/validate/index.ts +0 -58
  70. package/src/error.ts +0 -5
  71. /package/dist/composables/{http → request}/adapters/alist.d.ts +0 -0
  72. /package/dist/composables/{http → request}/adapters/base.d.ts +0 -0
  73. /package/dist/composables/{http → request}/adapters/cos.d.ts +0 -0
  74. /package/dist/composables/{http → request}/adapters/index.d.ts +0 -0
  75. /package/dist/composables/{http → request}/adapters/oss.d.ts +0 -0
  76. /package/dist/composables/{http → request}/adapters/qiniu.d.ts +0 -0
  77. /package/src/composables/{http → request}/adapters/alist.ts +0 -0
  78. /package/src/composables/{http → request}/adapters/base.ts +0 -0
  79. /package/src/composables/{http → request}/adapters/cos.ts +0 -0
  80. /package/src/composables/{http → request}/adapters/index.ts +0 -0
  81. /package/src/composables/{http → request}/adapters/qiniu.ts +0 -0
@@ -1,8 +1,7 @@
1
1
  /**
2
- * useDevice 设备信息 composable(单例缓存)
3
- * 使用微信 3.7.0+ 推荐的新 API 替代废弃的 getSystemInfoSync
2
+ * useDevice - 设备信息与接口 query
4
3
  */
5
- import { ref } from "vue";
4
+ import { useUtils } from "../utils";
6
5
 
7
6
  export interface DeviceInfo {
8
7
  /** 小程序 appId */
@@ -63,106 +62,134 @@ export interface DeviceInfo {
63
62
  version: string;
64
63
  }
65
64
 
66
- const _info = ref<DeviceInfo | null>(null);
65
+ export type DeviceQueryInfo = Pick<DeviceInfo,
66
+ | "appid"
67
+ | "device_brand"
68
+ | "device_model"
69
+ | "device_id"
70
+ | "device_type"
71
+ | "device_orientation"
72
+ | "platform"
73
+ | "system"
74
+ | "os"
75
+ | "version"
76
+ | "sdk_version"
77
+ | "host_name"
78
+ | "host_version"
79
+ | "host_language"
80
+ | "language"
81
+ | "app_version"
82
+ | "app_version_code"
83
+ | "screen_width"
84
+ | "screen_height"
85
+ >;
67
86
 
68
- /**
69
- * 安全调用 uni API,失败时返回空对象,避免平台差异导致中断。
70
- */
71
- function tryCall(fn: (() => unknown) | undefined): Record<string, unknown> {
72
- try { return (fn?.() ?? {}) as Record<string, unknown>; } catch { return {}; }
87
+ let deviceCache: DeviceInfo | null = null;
88
+
89
+ function readSafe(fn: (() => unknown) | undefined): Record<string, unknown> {
90
+ try {
91
+ return (fn?.() ?? {}) as Record<string, unknown>;
92
+ } catch {
93
+ return {};
94
+ }
73
95
  }
74
96
 
75
- /**
76
- * 收集当前设备、窗口与宿主应用信息并归一化字段。
77
- */
78
- function collect(): DeviceInfo {
79
- // @ts-ignore — 新 API 在旧版 @dcloudio/types 中可能未声明
80
- let deviceInfo = tryCall(uni.getDeviceInfo);
97
+ function collectDevice(): DeviceInfo {
98
+ // @ts-ignore - 新 API 在旧版 @dcloudio/types 中可能未声明。
99
+ let device = readSafe(uni.getDeviceInfo);
81
100
  // @ts-ignore
82
- let windowInfo = tryCall(uni.getWindowInfo);
83
- let appBaseInfo = tryCall(uni.getAppBaseInfo);
101
+ let window = readSafe(uni.getWindowInfo);
102
+ let app = readSafe(uni.getAppBaseInfo);
84
103
 
85
- if (!deviceInfo.brand && !deviceInfo.model) {
86
- const sys = tryCall(() => uni.getSystemInfoSync());
87
- deviceInfo = { ...sys };
88
- windowInfo = { ...sys };
89
- appBaseInfo = { ...sys };
104
+ if (!device.brand && !device.model) {
105
+ const system = readSafe(() => uni.getSystemInfoSync());
106
+ device = { ...system };
107
+ window = { ...system };
108
+ app = { ...system };
90
109
  }
91
110
 
92
- let appid = "";
93
- try {
94
- const accountInfo = uni.getAccountInfoSync() as { miniProgram?: { appId?: string } };
95
- appid = accountInfo?.miniProgram?.appId || "";
96
- } catch {
97
- appid = (deviceInfo.appId as string) || "";
98
- }
99
-
100
- const system = (deviceInfo.system as string) || "";
111
+ const system = (device.system as string) || "";
101
112
 
102
113
  return {
103
- appid,
104
- app_name: (appBaseInfo.appName as string) || "",
105
- app_version: (appBaseInfo.appVersion as string) || "",
106
- app_version_code: (appBaseInfo.appVersionCode as string) || "",
107
- app_channel: (appBaseInfo.appChannel as string) || "",
108
- device_brand: (deviceInfo.brand as string) || "",
109
- device_model: (deviceInfo.model as string) || "",
110
- device_id: (deviceInfo.deviceId as string) || "",
111
- device_type: (deviceInfo.deviceType as string) || "",
112
- device_orientation: (windowInfo.deviceOrientation as "portrait" | "landscape") || "portrait",
113
- brand: (deviceInfo.brand as string) || "",
114
- model: (deviceInfo.model as string) || "",
114
+ appid: getAppid(device),
115
+ app_name: (app.appName as string) || "",
116
+ app_version: (app.appVersion as string) || "",
117
+ app_version_code: (app.appVersionCode as string) || "",
118
+ app_channel: (app.appChannel as string) || "",
119
+ device_brand: (device.brand as string) || "",
120
+ device_model: (device.model as string) || "",
121
+ device_id: (device.deviceId as string) || "",
122
+ device_type: (device.deviceType as string) || "",
123
+ device_orientation: (window.deviceOrientation as "portrait" | "landscape") || "portrait",
124
+ brand: (device.brand as string) || "",
125
+ model: (device.model as string) || "",
115
126
  system,
116
127
  os: system.split(" ")[0] || "",
117
- pixel_ratio: (windowInfo.pixelRatio as number) || 0,
118
- screen_width: (windowInfo.screenWidth as number) || 0,
119
- screen_height: (windowInfo.screenHeight as number) || 0,
120
- window_width: (windowInfo.windowWidth as number) || 0,
121
- window_height: (windowInfo.windowHeight as number) || 0,
122
- status_bar_height: (windowInfo.statusBarHeight as number) || 0,
123
- sdk_version: (appBaseInfo.SDKVersion as string) || "",
124
- host_name: (appBaseInfo.hostName as string) || "",
125
- host_version: (appBaseInfo.hostVersion as string) || "",
126
- host_language: (appBaseInfo.hostLanguage as string) || "",
127
- host_theme: (appBaseInfo.hostTheme as string) || "",
128
- platform: (deviceInfo.platform as string) || "",
129
- language: (appBaseInfo.language as string) || "",
130
- version: (appBaseInfo.version as string) || "",
128
+ pixel_ratio: (window.pixelRatio as number) || 0,
129
+ screen_width: (window.screenWidth as number) || 0,
130
+ screen_height: (window.screenHeight as number) || 0,
131
+ window_width: (window.windowWidth as number) || 0,
132
+ window_height: (window.windowHeight as number) || 0,
133
+ status_bar_height: (window.statusBarHeight as number) || 0,
134
+ sdk_version: (app.SDKVersion as string) || "",
135
+ host_name: (app.hostName as string) || "",
136
+ host_version: (app.hostVersion as string) || "",
137
+ host_language: (app.hostLanguage as string) || "",
138
+ host_theme: (app.hostTheme as string) || "",
139
+ platform: (device.platform as string) || "",
140
+ language: (app.language as string) || "",
141
+ version: (app.version as string) || "",
131
142
  };
132
143
  }
133
144
 
134
- /**
135
- * 确保设备信息只在首次访问时采集一次。
136
- */
137
- function ensure() {
138
- if (!_info.value) {
139
- _info.value = collect();
145
+ function getAppid(device: Record<string, unknown>) {
146
+ try {
147
+ const account = uni.getAccountInfoSync() as { miniProgram?: { appId?: string } };
148
+ return account?.miniProgram?.appId || "";
149
+ } catch {
150
+ return (device.appId as string) || "";
140
151
  }
141
152
  }
142
153
 
143
- /**
144
- * 获取单例缓存的设备信息。
145
- */
146
- export function useDevice() {
147
- ensure();
148
- return _info;
154
+ function getDevice() {
155
+ deviceCache ??= collectDevice();
156
+ return deviceCache;
149
157
  }
150
158
 
151
- /**
152
- * 把 deviceInfo 对象转成 URL query string(不含前导 ?)
153
- */
154
- export function deviceToQuery(): string {
155
- ensure();
156
- if (!_info.value) return "";
157
- return Object.entries(_info.value)
158
- .filter(([, v]) => v !== "" && v !== 0)
159
- .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
160
- .join("&");
159
+ function getQueryInfo(info: DeviceInfo): DeviceQueryInfo {
160
+ return {
161
+ appid: info.appid,
162
+ device_brand: info.device_brand,
163
+ device_model: info.device_model,
164
+ device_id: info.device_id,
165
+ device_type: info.device_type,
166
+ device_orientation: info.device_orientation,
167
+ platform: info.platform,
168
+ system: info.system,
169
+ os: info.os,
170
+ version: info.version,
171
+ sdk_version: info.sdk_version,
172
+ host_name: info.host_name,
173
+ host_version: info.host_version,
174
+ host_language: info.host_language,
175
+ language: info.language,
176
+ app_version: info.app_version,
177
+ app_version_code: info.app_version_code,
178
+ screen_width: info.screen_width,
179
+ screen_height: info.screen_height,
180
+ };
181
+ }
182
+
183
+ export function useDevice() {
184
+ const info = getDevice();
185
+ const { toQuery } = useUtils();
186
+
187
+ return {
188
+ info,
189
+ query: toQuery(getQueryInfo(info)),
190
+ };
161
191
  }
162
192
 
163
- /**
164
- * 手动清除缓存(切换账号等场景可能需要)
165
- */
166
193
  export function clearDeviceCache(): void {
167
- _info.value = null;
194
+ deviceCache = null;
168
195
  }
@@ -1,51 +1,22 @@
1
1
  /**
2
2
  * Composables 统一导出
3
3
  */
4
- export * from "./http";
5
- export { useLoading } from "./loading";
4
+ export * from "./request";
6
5
  export { useMsg, type HlwMsg, type ToastOptions, type ModalOptions, type ToastIcon } from "./msg";
7
- export { useDevice, deviceToQuery, clearDeviceCache, type DeviceInfo } from "./device";
8
- export { useRefs } from "./refs";
9
- export { usePageMeta } from "./page-meta";
10
- export { useStorage, type StorageInstance } from "./storage";
11
- export { useValidate } from "./validate";
12
- export { useFormat } from "./format";
13
6
  export {
14
- useAd,
15
- setConfigAd,
16
- destroyAds,
17
- type AdType,
18
- type AdConfig,
19
- type AdError,
20
- type AdAdapter,
21
- type AdCloseResult,
22
- } from "./ad";
7
+ useDevice,
8
+ clearDeviceCache,
9
+ type DeviceInfo,
10
+ type DeviceQueryInfo,
11
+ } from "./device";
12
+ export { useRefs } from "./refs";
23
13
  export {
24
14
  useShare,
25
- useShareConfig,
26
- setConfigShare,
27
15
  type ShareConfig,
28
- type ShareConfigResolver,
29
- type ShareFrom,
30
- type ShareAppMessageContent,
31
- type ShareTimelineContent,
32
- type ShareConfigMap,
33
- type ShareConfigAdapter,
34
- type PageShareItem,
35
- type PageShareFallback,
36
- type SharePayload,
37
16
  } from "./share";
38
- export {
39
- useContact,
40
- setConfigContact,
41
- type ContactConfig,
42
- type ContactAdapter,
43
- type ContactBindProps,
44
- } from "./contact";
45
- export { useUtils, type DownloadFileOptions, type DownloadFileResult, type TapEvent } from "./utils";
46
- export { useColor } from "./color";
47
- export { useRouter, type NavigateType, type NavigateOptions } from "./navigator";
48
- export { useUuid } from "./algo";
17
+ export { useHlwAd, type AdRes } from "./ad";
18
+ export { useUtils, type DownloadOpt, type DownloadRes } from "./utils";
19
+ export { useNavigate, type NavigateType, type NavigateOptions } from "./navigator";
49
20
 
50
21
  // Theme(mp-vue 自带)
51
22
  export type { FontScale, FontPreset } from "./theme";
@@ -0,0 +1,79 @@
1
+ # msg 调用文档
2
+
3
+ `useMsg` 统一封装 toast、loading、modal 和简单进度展示。
4
+
5
+ ## 引入
6
+
7
+ ```ts
8
+ import { useMsg } from "@hlw-uni/mp-vue";
9
+ ```
10
+
11
+ ## 基础用法
12
+
13
+ ```ts
14
+ const msg = useMsg();
15
+
16
+ msg.toast("保存中");
17
+ msg.success("保存成功");
18
+ msg.error("保存失败");
19
+
20
+ msg.showLoading("加载中...");
21
+ msg.hideLoading();
22
+ ```
23
+
24
+ ## 确认弹窗
25
+
26
+ ```ts
27
+ const ok = await msg.confirm({
28
+ title: "删除确认",
29
+ content: "确定删除这条记录吗?",
30
+ confirmText: "删除",
31
+ });
32
+
33
+ if (ok) {
34
+ // 用户点击确认
35
+ }
36
+ ```
37
+
38
+ `modal` 是 `confirm` 的语义别名。
39
+
40
+ ## API
41
+
42
+ | 方法 | 说明 |
43
+ | --- | --- |
44
+ | `toast(opts | string)` | 普通提示 |
45
+ | `success(message)` | 成功提示 |
46
+ | `error(message)` | 失败提示 |
47
+ | `fail(message)` | `error` 的别名 |
48
+ | `showLoading(message?)` | 显示全局 loading |
49
+ | `hideLoading()` | 关闭全局 loading |
50
+ | `confirm(opts)` | 确认弹窗,返回 `Promise<boolean>` |
51
+ | `modal(opts)` | `confirm` 的别名 |
52
+ | `setLoadingBar(progress)` | 用导航标题模拟进度 |
53
+
54
+ ## ToastOptions
55
+
56
+ ```ts
57
+ interface ToastOptions {
58
+ message: string;
59
+ icon?: "success" | "fail" | "exception" | "none";
60
+ image?: string;
61
+ duration?: number;
62
+ mask?: boolean;
63
+ position?: "top" | "center" | "bottom";
64
+ }
65
+ ```
66
+
67
+ ## ModalOptions
68
+
69
+ ```ts
70
+ interface ModalOptions {
71
+ title?: string;
72
+ content: string;
73
+ confirmText?: string;
74
+ cancelText?: string;
75
+ confirmColor?: string;
76
+ cancelColor?: string;
77
+ showCancel?: boolean;
78
+ }
79
+ ```
@@ -0,0 +1,71 @@
1
+ # navigator 调用文档
2
+
3
+ `useNavigate` 统一封装 uni-app 页面跳转、tab 跳转、返回和打开其他小程序。
4
+
5
+ ## 引入
6
+
7
+ ```ts
8
+ import { useNavigate } from "@hlw-uni/mp-vue";
9
+ ```
10
+
11
+ ## 基础用法
12
+
13
+ ```ts
14
+ const nav = useNavigate();
15
+
16
+ nav.to("/pages/detail/index?id=1");
17
+ nav.redirect("/pages/login/index");
18
+ nav.tab("/pages/index/index");
19
+ nav.reLaunch("/pages/index/index");
20
+ nav.back();
21
+ ```
22
+
23
+ ## 打开其他小程序
24
+
25
+ ```ts
26
+ nav.miniProgram("wx1234567890", {
27
+ path: "pages/index/index?id=1",
28
+ envVersion: "release",
29
+ extraData: {
30
+ from: "hlw",
31
+ },
32
+ });
33
+ ```
34
+
35
+ ## 通用跳转
36
+
37
+ ```ts
38
+ nav.navigate("navigateTo", "/pages/detail/index?id=1", {
39
+ silent: true,
40
+ onFail: (message) => {
41
+ console.log(message);
42
+ },
43
+ });
44
+ ```
45
+
46
+ ## API
47
+
48
+ | 方法 | 说明 |
49
+ | --- | --- |
50
+ | `navigate(type, url, options?)` | 通用跳转入口 |
51
+ | `to(url, options?)` | `uni.navigateTo` |
52
+ | `redirect(url, options?)` | `uni.redirectTo` |
53
+ | `tab(url, options?)` | `uni.switchTab` |
54
+ | `reLaunch(url, options?)` | `uni.reLaunch` |
55
+ | `back(delta?, options?)` | `uni.navigateBack` |
56
+ | `miniProgram(appId, options?)` | `uni.navigateToMiniProgram` |
57
+
58
+ ## NavigateOptions
59
+
60
+ ```ts
61
+ interface NavigateOptions {
62
+ silent?: boolean;
63
+ onFail?: (message: string) => void;
64
+ delta?: number;
65
+ path?: string;
66
+ envVersion?: "develop" | "trial" | "release";
67
+ extraData?: Record<string, unknown>;
68
+ }
69
+ ```
70
+
71
+ `webview` 类型当前只提示 `H5:{url}`,具体 web-view 承载页由业务项目实现。
@@ -1,104 +1,104 @@
1
1
  /**
2
- * 路由/跳转能力 —— 包装 uni-app 各类 jump API 为一个统一对象
3
- *
4
- * 使用:
5
- * const { navigate } = useRouter();
6
- * navigate(tool.jump_type, tool.jump_value);
7
- *
8
- * 未装 vue-router 也能用;命名风格对齐 Vue Router,熟悉的 push/replace/back
9
- * 会在后续迭代中补齐。
2
+ * useNavigate - uni-app 跳转工具
10
3
  */
11
-
12
- /** 已知的跳转类型;保留 `(string & {})` 允许任意自定义值向下兼容 */
13
4
  export type NavigateType =
14
5
  | "navigateTo"
15
6
  | "redirectTo"
16
7
  | "switchTab"
17
8
  | "reLaunch"
18
- | "webview"
9
+ | "navigateBack"
19
10
  | "miniprogram"
11
+ | "webview"
20
12
  | (string & {});
21
13
 
22
14
  export interface NavigateOptions {
23
- /** 失败回调,收到 uni 返回的错误信息 */
24
- onFail?: (errMsg: string) => void;
25
- /** 是否禁用默认的 Toast 错误提示,默认 false */
26
15
  silent?: boolean;
27
- /** miniprogram:目标小程序的页面路径(如 pages/index/index?id=1),留空/null 则打开首页 */
28
- path?: string | null;
29
- /** 仅 miniprogram:目标小程序版本,默认 release */
16
+ onFail?: (message: string) => void;
17
+ delta?: number;
18
+ path?: string;
30
19
  envVersion?: "develop" | "trial" | "release";
31
- /** miniprogram:传给目标小程序的额外数据,对方从 onLaunch/onShow 读取 */
32
- extraData?: Record<string, unknown> | null;
20
+ extraData?: Record<string, unknown>;
33
21
  }
34
22
 
35
- /**
36
- * 根据 type + value 调用对应的 uni API,屏蔽参数差异。
37
- *
38
- * 对应关系:
39
- * - `navigateTo`(默认) → uni.navigateTo
40
- * - `redirectTo` → uni.redirectTo
41
- * - `switchTab` → uni.switchTab(value 必须是 tabBar 页)
42
- * - `reLaunch` → uni.reLaunch
43
- * - `webview` → 默认 Toast 提示,上层需接入 web-view 承载页
44
- * - `miniprogram` → uni.navigateToMiniProgram,value 格式 `appid:path`
45
- */
46
- function doNavigate(type: NavigateType, value: string, options: NavigateOptions = {}): void {
47
- const { onFail, silent = false } = options;
23
+ type UniFail = { errMsg?: string };
48
24
 
49
- if (!value) {
50
- if (!silent) uni.showToast({ title: "跳转目标未配置", icon: "none" });
51
- onFail?.("跳转目标未配置");
52
- return;
25
+ function fail(message: string, options: NavigateOptions = {}) {
26
+ if (!options.silent) {
27
+ uni.showToast({ title: message, icon: "none" });
53
28
  }
29
+ options.onFail?.(message);
30
+ }
54
31
 
55
- const fail = (err?: { errMsg?: string }) => {
56
- const msg = err?.errMsg || `无法跳转:${value}`;
57
- if (!silent) uni.showToast({ title: msg, icon: "none" });
58
- onFail?.(msg);
32
+ function failHandler(target: string, options: NavigateOptions = {}) {
33
+ return (error?: UniFail) => {
34
+ fail(error?.errMsg || `无法跳转:${target}`, options);
59
35
  };
36
+ }
60
37
 
61
- switch (type) {
62
- case "switchTab":
63
- uni.switchTab({ url: value, fail });
64
- break;
65
- case "redirectTo":
66
- uni.redirectTo({ url: value, fail });
67
- break;
68
- case "reLaunch":
69
- uni.reLaunch({ url: value, fail });
70
- break;
71
- case "webview":
72
- // H5 需要上层承载页接入;这里仅 Toast 告知
73
- if (!silent) uni.showToast({ title: `H5:${value}`, icon: "none" });
74
- break;
75
- case "miniprogram": {
76
- // @ts-ignore 部分平台 navigateToMiniProgram 定义可能缺失
77
- uni.navigateToMiniProgram?.({
78
- appId: value,
79
- path: options.path || "",
80
- envVersion: options.envVersion,
81
- extraData: options.extraData ?? undefined,
82
- fail,
83
- });
84
- break;
38
+ function navigate(type: NavigateType = "navigateTo", url = "", options: NavigateOptions = {}) {
39
+ if (type === "navigateBack") {
40
+ uni.navigateBack({ delta: options.delta || 1, fail: failHandler("返回上一页", options) });
41
+ return;
42
+ }
43
+
44
+ if (!url) {
45
+ fail("跳转目标未配置", options);
46
+ return;
47
+ }
48
+
49
+ const onFail = failHandler(url, options);
50
+
51
+ if (type === "redirectTo") {
52
+ uni.redirectTo({ url, fail: onFail });
53
+ return;
54
+ }
55
+
56
+ if (type === "switchTab") {
57
+ uni.switchTab({ url, fail: onFail });
58
+ return;
59
+ }
60
+
61
+ if (type === "reLaunch") {
62
+ uni.reLaunch({ url, fail: onFail });
63
+ return;
64
+ }
65
+
66
+ if (type === "miniprogram") {
67
+ const openMiniProgram = uni.navigateToMiniProgram as
68
+ | ((options: UniApp.NavigateToMiniProgramOptions) => void)
69
+ | undefined;
70
+
71
+ if (!openMiniProgram) {
72
+ fail("当前平台不支持打开小程序", options);
73
+ return;
85
74
  }
86
- case "navigateTo":
87
- default:
88
- uni.navigateTo({ url: value, fail });
89
- break;
75
+
76
+ openMiniProgram({
77
+ appId: url,
78
+ path: options.path || "",
79
+ envVersion: options.envVersion || "release",
80
+ extraData: options.extraData,
81
+ fail: onFail,
82
+ });
83
+ return;
84
+ }
85
+
86
+ if (type === "webview") {
87
+ fail(`H5:${url}`, options);
88
+ return;
90
89
  }
90
+
91
+ uni.navigateTo({ url, fail: onFail });
91
92
  }
92
93
 
93
- /**
94
- * 路由 composable:返回跳转方法集合。
95
- *
96
- * @example
97
- * const { navigate } = useRouter();
98
- * navigate("switchTab", "/pages/index/index");
99
- */
100
- export function useRouter() {
94
+ export function useNavigate() {
101
95
  return {
102
- navigate: doNavigate,
96
+ navigate,
97
+ to: (url: string, options?: NavigateOptions) => navigate("navigateTo", url, options),
98
+ redirect: (url: string, options?: NavigateOptions) => navigate("redirectTo", url, options),
99
+ tab: (url: string, options?: NavigateOptions) => navigate("switchTab", url, options),
100
+ reLaunch: (url: string, options?: NavigateOptions) => navigate("reLaunch", url, options),
101
+ back: (delta = 1, options: NavigateOptions = {}) => navigate("navigateBack", "", { ...options, delta }),
102
+ miniProgram: (appId: string, options?: NavigateOptions) => navigate("miniprogram", appId, options),
103
103
  };
104
104
  }
@@ -0,0 +1,40 @@
1
+ # refs 调用文档
2
+
3
+ `useRefs` 用于 `v-for` 场景批量收集组件或元素引用。
4
+
5
+ ## 引入
6
+
7
+ ```ts
8
+ import { useRefs } from "@hlw-uni/mp-vue";
9
+ ```
10
+
11
+ ## 基础用法
12
+
13
+ ```vue
14
+ <template>
15
+ <hlw-popup
16
+ v-for="item in list"
17
+ :key="item.id"
18
+ :ref="setRefs(item.id)"
19
+ />
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ import { useRefs } from "@hlw-uni/mp-vue";
24
+
25
+ const { refs, setRefs } = useRefs();
26
+
27
+ function open(id: string) {
28
+ refs.value[id]?.open?.();
29
+ }
30
+ </script>
31
+ ```
32
+
33
+ ## 返回值
34
+
35
+ | 字段 | 说明 |
36
+ | --- | --- |
37
+ | `refs` | `Record<string, any>` 的响应式引用集合 |
38
+ | `setRefs(key)` | 返回可绑定到模板 `ref` 的回调函数 |
39
+
40
+ 组件更新前和卸载时,内部会自动清空引用集合,避免旧引用残留。