@hlw-uni/mp-vue 2.1.51 → 2.1.54

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 (75) hide show
  1. package/dist/app.d.ts +2 -20
  2. package/dist/composables/device/index.d.ts +5 -70
  3. package/dist/composables/index.d.ts +5 -14
  4. package/dist/composables/navigator/index.d.ts +15 -39
  5. package/dist/composables/request/client.d.ts +21 -0
  6. package/dist/composables/request/index.d.ts +6 -0
  7. package/dist/composables/request/service.d.ts +30 -0
  8. package/dist/composables/{http → request}/types.d.ts +0 -3
  9. package/dist/composables/share/index.d.ts +7 -66
  10. package/dist/composables/theme/appearance.d.ts +3 -2
  11. package/dist/composables/theme/index.d.ts +5 -7
  12. package/dist/composables/utils/index.d.ts +25 -32
  13. package/dist/hlw.d.ts +2 -4
  14. package/dist/index.d.ts +2 -3
  15. package/dist/index.js +485 -1269
  16. package/dist/index.mjs +484 -1268
  17. package/package.json +2 -1
  18. package/src/app.ts +3 -143
  19. package/src/components/hlw-ad/index.vue +2 -2
  20. package/src/components/hlw-page/index.vue +1 -1
  21. package/src/composables/device/index.ts +110 -83
  22. package/src/composables/index.ts +9 -39
  23. package/src/composables/navigator/index.ts +77 -77
  24. package/src/composables/request/client.ts +204 -0
  25. package/src/composables/request/index.ts +15 -0
  26. package/src/composables/request/service.ts +54 -0
  27. package/src/composables/{http → request}/types.ts +0 -4
  28. package/src/composables/share/index.ts +64 -168
  29. package/src/composables/theme/appearance.ts +3 -2
  30. package/src/composables/theme/index.ts +11 -28
  31. package/src/composables/theme/palette.ts +22 -4
  32. package/src/composables/utils/index.ts +131 -95
  33. package/src/hlw.ts +6 -14
  34. package/src/index.ts +2 -3
  35. package/dist/composables/_internal/unwrap.d.ts +0 -15
  36. package/dist/composables/ad/index.d.ts +0 -78
  37. package/dist/composables/algo/index.d.ts +0 -7
  38. package/dist/composables/algo/uuid.d.ts +0 -17
  39. package/dist/composables/color/index.d.ts +0 -8
  40. package/dist/composables/contact/index.d.ts +0 -32
  41. package/dist/composables/format/index.d.ts +0 -9
  42. package/dist/composables/http/client.d.ts +0 -66
  43. package/dist/composables/http/index.d.ts +0 -8
  44. package/dist/composables/loading/index.d.ts +0 -7
  45. package/dist/composables/page-meta/index.d.ts +0 -18
  46. package/dist/composables/storage/index.d.ts +0 -16
  47. package/dist/composables/validate/index.d.ts +0 -12
  48. package/dist/error.d.ts +0 -1
  49. package/src/composables/_internal/unwrap.ts +0 -19
  50. package/src/composables/ad/index.ts +0 -412
  51. package/src/composables/algo/index.ts +0 -7
  52. package/src/composables/algo/uuid.ts +0 -27
  53. package/src/composables/color/index.ts +0 -44
  54. package/src/composables/contact/index.ts +0 -92
  55. package/src/composables/format/index.ts +0 -48
  56. package/src/composables/http/client.ts +0 -237
  57. package/src/composables/http/index.ts +0 -8
  58. package/src/composables/http/useRequest.ts +0 -107
  59. package/src/composables/loading/index.ts +0 -23
  60. package/src/composables/page-meta/index.ts +0 -49
  61. package/src/composables/storage/index.ts +0 -76
  62. package/src/composables/validate/index.ts +0 -58
  63. package/src/error.ts +0 -5
  64. /package/dist/composables/{http → request}/adapters/alist.d.ts +0 -0
  65. /package/dist/composables/{http → request}/adapters/base.d.ts +0 -0
  66. /package/dist/composables/{http → request}/adapters/cos.d.ts +0 -0
  67. /package/dist/composables/{http → request}/adapters/index.d.ts +0 -0
  68. /package/dist/composables/{http → request}/adapters/oss.d.ts +0 -0
  69. /package/dist/composables/{http → request}/adapters/qiniu.d.ts +0 -0
  70. /package/src/composables/{http → request}/adapters/alist.ts +0 -0
  71. /package/src/composables/{http → request}/adapters/base.ts +0 -0
  72. /package/src/composables/{http → request}/adapters/cos.ts +0 -0
  73. /package/src/composables/{http → request}/adapters/index.ts +0 -0
  74. /package/src/composables/{http → request}/adapters/oss.ts +0 -0
  75. /package/src/composables/{http → request}/adapters/qiniu.ts +0 -0
@@ -1,189 +1,85 @@
1
- /**
2
- * useShare - 小程序分享 composable
3
- *
4
- * 两层 API 并存:
5
- * - useShare(config) —— SDK 层:直接注册 onShareAppMessage / onShareTimeline 钩子
6
- * - useShareConfig(...) —— 业务层:lazy load 后端配置 + cache + fallback resolver
7
- */
8
- import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app';
9
- import { ref } from 'vue';
10
- import { unwrapPayload, type AdapterPayload } from '../_internal/unwrap';
1
+ import {
2
+ onShareAppMessage as registerShareAppMessage,
3
+ onShareTimeline as registerShareTimeline,
4
+ } from "@dcloudio/uni-app";
11
5
 
12
- export interface ShareAppMessageContent {
13
- /** 分享标题 */
6
+ export interface ShareConfig {
14
7
  title?: string;
15
- /** 分享路径,必须是以 / 开头的完整路径 */
16
8
  path?: string;
17
- /** 自定义图片路径 */
18
9
  imageUrl?: string;
19
10
  }
20
11
 
21
- export interface ShareTimelineContent {
22
- /** 朋友圈分享标题 */
23
- title?: string;
24
- /** 页面携带的 query 参数 */
25
- query?: string;
26
- /** 自定义图片路径 */
27
- imageUrl?: string;
28
- }
29
-
30
- export interface ShareConfig extends ShareAppMessageContent {
31
- /** 朋友圈专属配置,不填则复用朋友分享配置 */
32
- timeline?: ShareTimelineContent;
33
- }
34
-
35
- /**
36
- * 分享来源。
37
- * - `button` 页面内转发按钮
38
- * - `menu` 右上角菜单
39
- */
40
- export type ShareFrom = 'button' | 'menu';
12
+ export type ShareConfigResolver = ShareConfig | (() => ShareConfig);
41
13
 
42
- export type ShareConfigResolver = (from: ShareFrom) => ShareConfig;
43
-
44
- /**
45
- * 注册小程序分享钩子。
46
- */
47
- export function useShare(config: ShareConfig | ShareConfigResolver) {
48
- /**
49
- * 根据分享来源解析最终分享配置。
50
- */
51
- const resolve = (from: ShareFrom): ShareConfig =>
52
- typeof config === 'function' ? config(from) : config;
53
-
54
- /**
55
- * 注册分享给朋友的回调。
56
- */
57
- onShareAppMessage((options: { from?: string } | undefined) => {
58
- const resolved = resolve((options?.from as ShareFrom) ?? 'menu');
59
- const payload: ShareAppMessageContent = {};
60
- if (resolved.title !== undefined) payload.title = resolved.title;
61
- if (resolved.path !== undefined) payload.path = resolved.path;
62
- if (resolved.imageUrl !== undefined) payload.imageUrl = resolved.imageUrl;
63
- return payload;
64
- });
65
-
66
- /**
67
- * 注册分享到朋友圈的回调。
68
- */
69
- onShareTimeline(() => {
70
- const resolved = resolve('menu');
71
- const timeline = resolved.timeline ?? {};
72
- const payload: ShareTimelineContent = {};
73
- const title = timeline.title ?? resolved.title;
74
- const imageUrl = timeline.imageUrl ?? resolved.imageUrl;
75
- if (title !== undefined) payload.title = title;
76
- if (timeline.query !== undefined) payload.query = timeline.query;
77
- if (imageUrl !== undefined) payload.imageUrl = imageUrl;
78
- return payload;
79
- });
14
+ export interface ShareHandlers {
15
+ onShareAppMessage: (config?: ShareConfigResolver) => void;
16
+ onShareTimeline: (config?: ShareConfigResolver) => void;
17
+ showShareMenu: () => void;
80
18
  }
81
19
 
82
- /* ============================================================
83
- * useShareConfig —— 业务层:lazy load 后端聚合配置 + cache + fallback resolver
84
- *
85
- * 后端按页面 key 聚合返回各页 title / image,前端拉一次缓存全局共用。
86
- * 返回的 resolver 同时喂给 onShareAppMessage 和 onShareTimeline。
87
- *
88
- * 使用方式:
89
- *
90
- * 1. App.vue / bootstrap 注入回调:
91
- *
92
- * setConfigShare({
93
- * getConfig: async () => {
94
- * const res = await getShareConfig();
95
- * return res.code === 1 ? res.data : null;
96
- * },
97
- * });
98
- *
99
- * 2. 任意页面 setup:
100
- *
101
- * const share = useShareConfig("index", {
102
- * title: "兜底标题",
103
- * path: "/pages/index/index",
104
- * });
105
- * onShareAppMessage(share);
106
- * onShareTimeline(share);
107
- * ============================================================ */
108
-
109
- /** 单页分享配置 */
110
- export interface PageShareItem {
111
- title: string;
112
- image: string;
20
+ function resolveConfig(config?: ShareConfigResolver): ShareConfig {
21
+ return typeof config === "function" ? config() : (config ?? {});
113
22
  }
114
23
 
115
- /** 后端返回的页面 key 配置映射 */
116
- export type ShareConfigMap = Record<string, PageShareItem>;
117
-
118
- /**
119
- * Adapter 注入接口 —— getConfig 支持「已解包」或「ThinkAdmin envelope」两种返回值。
120
- * 业务方可以直接传 envelope-returning 接口:setConfigShare({ getConfig: getShareConfig })
121
- */
122
- export interface ShareConfigAdapter {
123
- getConfig: () => Promise<AdapterPayload<ShareConfigMap>>;
124
- }
125
-
126
- /** 页面声明的兜底文案 / 跳转路径 */
127
- export interface PageShareFallback {
128
- /** 后端 title 为空时用 */
129
- title: string;
130
- /** 分享跳转路径(必须 / 开头);path 不走后端,由页面自定义 */
131
- path: string;
132
- /** 后端 image 为空时用;通常留空让微信自动截图 */
133
- image?: string;
24
+ function buildPayload(base: ShareConfigResolver, extra?: ShareConfigResolver): ShareConfig {
25
+ const current = {
26
+ ...resolveConfig(base),
27
+ ...resolveConfig(extra),
28
+ };
29
+ const payload: ShareConfig = {};
30
+ if (current.title) payload.title = current.title;
31
+ if (current.path) payload.path = current.path;
32
+ if (current.imageUrl) payload.imageUrl = current.imageUrl;
33
+ return payload;
134
34
  }
135
35
 
136
- /** 分享 payload —— 同时喂给 onShareAppMessage / onShareTimeline */
137
- export interface SharePayload {
138
- title: string;
139
- path: string;
140
- imageUrl?: string;
36
+ function showShareMenu(): void {
37
+ const api = typeof uni !== "undefined" ? (uni as unknown as {
38
+ showShareMenu?: (options: {
39
+ withShareTicket?: boolean;
40
+ menus?: string[];
41
+ fail?: () => void;
42
+ }) => void;
43
+ }) : undefined;
44
+
45
+ api?.showShareMenu?.({
46
+ withShareTicket: true,
47
+ menus: ["shareAppMessage", "shareTimeline"],
48
+ fail: () => undefined,
49
+ });
141
50
  }
142
51
 
143
- let shareAdapter: ShareConfigAdapter | null = null;
144
- const shareCache = ref<ShareConfigMap | null>(null);
145
- let sharePending: Promise<void> | null = null;
52
+ export function useShare(config: ShareConfigResolver = {}): ShareHandlers {
53
+ let appMessageRegistered = false;
54
+ let timelineRegistered = false;
146
55
 
147
- /**
148
- * 注入业务回调(应用启动时调用一次;不调用则始终用 fallback)。
149
- */
150
- export function setConfigShare(a: ShareConfigAdapter): void {
151
- shareAdapter = a;
152
- }
56
+ const onShareAppMessage = (extra?: ShareConfigResolver) => {
57
+ if (appMessageRegistered) return;
58
+ appMessageRegistered = true;
59
+ showShareMenu();
60
+ registerShareAppMessage(() => buildPayload(config, extra));
61
+ };
153
62
 
154
- function loadShareConfig(): Promise<void> {
155
- if (shareCache.value) return Promise.resolve();
156
- if (sharePending) return sharePending;
157
- if (!shareAdapter?.getConfig) {
158
- console.warn("[useShareConfig] adapter.getConfig 未注入;先调用 setConfigShare()");
159
- return Promise.resolve();
160
- }
161
- sharePending = shareAdapter.getConfig()
162
- .then((raw) => {
163
- const cfg = unwrapPayload(raw);
164
- if (cfg) shareCache.value = cfg;
165
- })
166
- .catch((e) => {
167
- console.warn("[useShareConfig] load failed", e);
168
- })
169
- .finally(() => {
170
- sharePending = null;
63
+ const onShareTimeline = (extra?: ShareConfigResolver) => {
64
+ if (timelineRegistered) return;
65
+ timelineRegistered = true;
66
+ showShareMenu();
67
+ registerShareTimeline(() => {
68
+ const payload = buildPayload(config, extra);
69
+ return {
70
+ title: payload.title,
71
+ query: payload.path?.split("?")[1],
72
+ imageUrl: payload.imageUrl,
73
+ };
171
74
  });
172
- return sharePending;
173
- }
75
+ };
76
+
77
+ onShareAppMessage();
78
+ onShareTimeline();
174
79
 
175
- /**
176
- * 业务级分享配置 helper —— 返回 resolver,可直接喂 onShareAppMessage / onShareTimeline。
177
- * 后端配置异步加载,加载完成前先用 fallback、加载完后自动切到后端值。
178
- */
179
- export function useShareConfig(pageKey: string, fallback: PageShareFallback) {
180
- void loadShareConfig();
181
- return (): SharePayload => {
182
- const remote = shareCache.value?.[pageKey];
183
- const title = remote?.title || fallback.title;
184
- const image = remote?.image || fallback.image;
185
- const payload: SharePayload = { title, path: fallback.path };
186
- if (image) payload.imageUrl = image;
187
- return payload;
80
+ return {
81
+ onShareAppMessage,
82
+ onShareTimeline,
83
+ showShareMenu,
188
84
  };
189
85
  }
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * 外观模式 — 浅色 / 深色 / 跟随系统
3
3
  *
4
- * 提供一套语义化 CSS 变量(--bg-page, --surface-card, --text-primary ...),
5
- * 页面通过 hlw-page `:page-style` 注入到 `page` 元素,让内部组件和样式统一消费。
4
+ * 提供一套语义化 CSS 变量(--bg-page, --surface-card, --text-primary ...)。
5
+ * 默认不通过 useThemePageStyle 注入,业务项目应在全局 CSS 中声明这些变量,
6
+ * 避免运行时 page-meta 覆盖业务侧样式。
6
7
  *
7
8
  * 使用指南:
8
9
  * - 业务样式里用 `var(--text-primary)` 代替硬编码 `#0f172a`
@@ -1,13 +1,8 @@
1
1
  import { computed } from "vue";
2
- import { useColor } from "@/composables/color";
3
2
  import { useThemeStore } from "../../stores/theme";
4
3
 
5
- const { varsToStyle } = useColor();
6
4
  import { getCurrentFontVars } from "./font";
7
5
  import { getCurrentThemeVars } from "./palette";
8
- import { getCurrentAppearanceVars } from "./appearance";
9
-
10
- const CSS_CONTROLLED_THEME_VARS = new Set(["--border-color", "--border-color-light", "--border-color-focus"]);
11
6
 
12
7
  /**
13
8
  * @deprecated 历史事件名;现已改用 pinia store 响应式驱动,emit 不再有效。
@@ -15,52 +10,40 @@ const CSS_CONTROLLED_THEME_VARS = new Set(["--border-color", "--border-color-lig
15
10
  */
16
11
  export const THEME_CHANGE_EVENT = "hlw:theme-change";
17
12
 
18
- function omitCssControlledThemeVars(vars: Record<string, string>) {
19
- const next: Record<string, string> = {};
20
-
21
- Object.entries(vars).forEach(([name, value]) => {
22
- if (!CSS_CONTROLLED_THEME_VARS.has(name)) {
23
- next[name] = value;
24
- }
25
- });
26
-
27
- return next;
28
- }
29
-
30
13
  /**
31
- * 只注入会随主题变化的变量(字号档位、主题色、外观模式)。
14
+ * 只注入运行时配置变量(字号档位、主题色)。
32
15
  *
33
- * 语义排版 token(--text-title-size 等)和业务视觉变量(如边框色)
34
- * 是静态值、不随主题变化,
35
- * 放在项目的全局 CSS(static/css/style.scss)里作为 page{} 默认值即可,
36
- * 让业务侧可以自由 override,不被运行时注入覆盖。
16
+ * 页面背景、卡片色、文字色、边框色等业务视觉变量统一由项目全局 CSS
17
+ * (static/css/style.scss)控制,避免 page-meta 运行时样式覆盖业务侧配置。
37
18
  */
38
19
  export function buildThemeStyle(): string {
39
20
  return varsToStyle({
40
21
  ...getCurrentFontVars(),
41
22
  ...getCurrentThemeVars(),
42
- ...omitCssControlledThemeVars(getCurrentAppearanceVars()),
43
23
  });
44
24
  }
45
25
 
26
+ function varsToStyle(vars: Record<string, string>): string {
27
+ return Object.entries(vars).map(([key, value]) => `${key}:${value}`).join(";") + ";";
28
+ }
29
+
46
30
  /**
47
31
  * 获取主题样式字符串,用于注入 <page-meta :page-style>。
48
32
  *
49
- * 实现走 pinia store 响应式:store.scale / primaryColor / appearance 任一变化
33
+ * 实现走 pinia store 响应式:store.scale / primaryColor 任一变化
50
34
  * → computed 重算 → page-meta 自动 setData。
51
35
  *
52
36
  * 注:早期版本用 uni.$emit + onMounted+uni.$on 事件总线驱动,在 vue3 + 小程序部分
53
- * 基础库下 emit 后 ref 不响应(导致字号 / 主题色 / 外观切换不生效)。已改成响应式驱动。
37
+ * 基础库下 emit 后 ref 不响应(导致字号 / 主题色切换不生效)。已改成响应式驱动。
54
38
  */
55
39
  export function useThemePageStyle() {
56
40
  const store = useThemeStore();
57
41
  const themePageStyle = computed(() => {
58
- // 显式 track 三个响应字段,触发 computed 重算
59
- // setScale / setTheme / setAppearance 内部已先 set storage 再改 ref,
42
+ // 显式 track 两个响应字段,触发 computed 重算
43
+ // setScale / setTheme 内部已先 set storage 再改 ref,
60
44
  // 所以 buildThemeStyle 从 storage 读到的一定是最新值
61
45
  void store.scale;
62
46
  void store.primaryColor;
63
- void store.appearance;
64
47
  return buildThemeStyle();
65
48
  });
66
49
  return { themePageStyle };
@@ -1,7 +1,3 @@
1
- import { useColor } from "@/composables/color";
2
-
3
- const { hexToRgba, darkenHex } = useColor();
4
-
5
1
  export interface ThemeColor {
6
2
  label: string;
7
3
  value: string;
@@ -65,3 +61,25 @@ export function getCurrentThemeVars(): Record<string, string> {
65
61
  "--info-dark": darkenHex(THEME_SEMANTIC_COLORS.info),
66
62
  };
67
63
  }
64
+
65
+ const HEX_RE = /^#[0-9a-fA-F]{6}$/;
66
+
67
+ function parseHex(hex: string): [number, number, number] {
68
+ if (!HEX_RE.test(hex)) throw new Error(`Invalid hex color: ${hex}`);
69
+ return [
70
+ parseInt(hex.slice(1, 3), 16),
71
+ parseInt(hex.slice(3, 5), 16),
72
+ parseInt(hex.slice(5, 7), 16),
73
+ ];
74
+ }
75
+
76
+ function hexToRgba(hex: string, alpha: number): string {
77
+ const [r, g, b] = parseHex(hex);
78
+ return `rgba(${r},${g},${b},${alpha})`;
79
+ }
80
+
81
+ function darkenHex(hex: string, amount = 0.15): string {
82
+ const [r, g, b] = parseHex(hex);
83
+ const darken = (value: number) => Math.max(0, Math.round(value * (1 - amount)));
84
+ return `#${darken(r).toString(16).padStart(2, "0")}${darken(g).toString(16).padStart(2, "0")}${darken(b).toString(16).padStart(2, "0")}`;
85
+ }