@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.
- package/dist/app.d.ts +2 -20
- package/dist/composables/ad/index.d.ts +11 -73
- package/dist/composables/device/index.d.ts +5 -70
- package/dist/composables/index.d.ts +6 -14
- package/dist/composables/navigator/index.d.ts +15 -39
- package/dist/composables/request/client.d.ts +21 -0
- package/dist/composables/request/index.d.ts +6 -0
- package/dist/composables/request/service.d.ts +30 -0
- package/dist/composables/{http → request}/types.d.ts +0 -3
- package/dist/composables/share/index.d.ts +7 -66
- package/dist/composables/utils/index.d.ts +25 -32
- package/dist/hlw.d.ts +2 -4
- package/dist/index.d.ts +2 -3
- package/dist/index.js +614 -1253
- package/dist/index.mjs +613 -1252
- package/package.json +2 -1
- package/src/app.ts +3 -143
- package/src/components/hlw-ad/index.vue +6 -5
- package/src/components/hlw-page/index.vue +1 -1
- package/src/composables/ad/README.md +58 -0
- package/src/composables/ad/index.ts +117 -376
- package/src/composables/device/README.md +50 -0
- package/src/composables/device/index.ts +110 -83
- package/src/composables/index.ts +10 -39
- package/src/composables/msg/README.md +79 -0
- package/src/composables/navigator/README.md +71 -0
- package/src/composables/navigator/index.ts +77 -77
- package/src/composables/refs/README.md +40 -0
- package/src/composables/request/README.md +124 -0
- package/src/composables/{http → request}/adapters/oss.ts +1 -0
- package/src/composables/request/client.ts +204 -0
- package/src/composables/request/index.ts +15 -0
- package/src/composables/request/service.ts +54 -0
- package/src/composables/{http → request}/types.ts +0 -4
- package/src/composables/share/README.md +53 -0
- package/src/composables/share/index.ts +64 -168
- package/src/composables/theme/README.md +131 -0
- package/src/composables/theme/index.ts +4 -2
- package/src/composables/theme/palette.ts +22 -4
- package/src/composables/utils/README.md +81 -0
- package/src/composables/utils/index.ts +131 -95
- package/src/hlw.ts +6 -14
- package/src/index.ts +2 -3
- package/dist/composables/_internal/unwrap.d.ts +0 -15
- package/dist/composables/algo/index.d.ts +0 -7
- package/dist/composables/algo/uuid.d.ts +0 -17
- package/dist/composables/color/index.d.ts +0 -8
- package/dist/composables/contact/index.d.ts +0 -32
- package/dist/composables/format/index.d.ts +0 -9
- package/dist/composables/http/client.d.ts +0 -66
- package/dist/composables/http/index.d.ts +0 -8
- package/dist/composables/loading/index.d.ts +0 -7
- package/dist/composables/page-meta/index.d.ts +0 -18
- package/dist/composables/storage/index.d.ts +0 -16
- package/dist/composables/validate/index.d.ts +0 -12
- package/dist/error.d.ts +0 -1
- package/src/composables/_internal/unwrap.ts +0 -19
- package/src/composables/algo/index.ts +0 -7
- package/src/composables/algo/uuid.ts +0 -27
- package/src/composables/color/index.ts +0 -44
- package/src/composables/contact/index.ts +0 -92
- package/src/composables/format/index.ts +0 -48
- package/src/composables/http/client.ts +0 -237
- package/src/composables/http/index.ts +0 -8
- package/src/composables/http/useRequest.ts +0 -107
- package/src/composables/loading/index.ts +0 -23
- package/src/composables/page-meta/index.ts +0 -49
- package/src/composables/storage/index.ts +0 -76
- package/src/composables/validate/index.ts +0 -58
- package/src/error.ts +0 -5
- /package/dist/composables/{http → request}/adapters/alist.d.ts +0 -0
- /package/dist/composables/{http → request}/adapters/base.d.ts +0 -0
- /package/dist/composables/{http → request}/adapters/cos.d.ts +0 -0
- /package/dist/composables/{http → request}/adapters/index.d.ts +0 -0
- /package/dist/composables/{http → request}/adapters/oss.d.ts +0 -0
- /package/dist/composables/{http → request}/adapters/qiniu.d.ts +0 -0
- /package/src/composables/{http → request}/adapters/alist.ts +0 -0
- /package/src/composables/{http → request}/adapters/base.ts +0 -0
- /package/src/composables/{http → request}/adapters/cos.ts +0 -0
- /package/src/composables/{http → request}/adapters/index.ts +0 -0
- /package/src/composables/{http → request}/adapters/qiniu.ts +0 -0
|
@@ -1,189 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
let
|
|
52
|
+
export function useShare(config: ShareConfigResolver = {}): ShareHandlers {
|
|
53
|
+
let appMessageRegistered = false;
|
|
54
|
+
let timelineRegistered = false;
|
|
146
55
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
56
|
+
const onShareAppMessage = (extra?: ShareConfigResolver) => {
|
|
57
|
+
if (appMessageRegistered) return;
|
|
58
|
+
appMessageRegistered = true;
|
|
59
|
+
showShareMenu();
|
|
60
|
+
registerShareAppMessage(() => buildPayload(config, extra));
|
|
61
|
+
};
|
|
153
62
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
173
|
-
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
onShareAppMessage();
|
|
78
|
+
onShareTimeline();
|
|
174
79
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# theme 调用文档
|
|
2
|
+
|
|
3
|
+
`theme` 模块提供字体档位、主题色、外观模式、排版 token 和 `page-meta` 样式注入能力。
|
|
4
|
+
|
|
5
|
+
## 引入
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import {
|
|
9
|
+
useThemePageStyle,
|
|
10
|
+
getCurrentFontScale,
|
|
11
|
+
getCurrentFontVars,
|
|
12
|
+
getCurrentThemeColor,
|
|
13
|
+
getCurrentThemeVars,
|
|
14
|
+
getCurrentAppearance,
|
|
15
|
+
getCurrentAppearanceMode,
|
|
16
|
+
getCurrentAppearanceVars,
|
|
17
|
+
getCurrentTypographyVars,
|
|
18
|
+
} from "@hlw-uni/mp-vue";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## useThemePageStyle
|
|
22
|
+
|
|
23
|
+
页面需要把主题 CSS 变量注入到小程序 page 根时使用。
|
|
24
|
+
|
|
25
|
+
```vue
|
|
26
|
+
<template>
|
|
27
|
+
<page-meta :page-style="themePageStyle" />
|
|
28
|
+
<hlw-page>
|
|
29
|
+
页面内容
|
|
30
|
+
</hlw-page>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { useThemePageStyle } from "@hlw-uni/mp-vue";
|
|
35
|
+
|
|
36
|
+
const { themePageStyle } = useThemePageStyle();
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
如果项目启用了 `@hlw-uni/mp-vite-plugin` 的 `themePageMeta`,页面可由插件自动注入 `<page-meta>` 和 `useThemePageStyle`。
|
|
41
|
+
|
|
42
|
+
## 字体档位
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const scale = getCurrentFontScale();
|
|
46
|
+
const vars = getCurrentFontVars();
|
|
47
|
+
|
|
48
|
+
console.log(scale, vars["--font-base"]);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
支持的 `FontScale`:
|
|
52
|
+
|
|
53
|
+
| 值 | 说明 |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| `small` | 较小 |
|
|
56
|
+
| `compact` | 略小 |
|
|
57
|
+
| `normal` | 标准 |
|
|
58
|
+
| `medium` | 适中 |
|
|
59
|
+
| `large` | 较大 |
|
|
60
|
+
| `xlarge` | 超大 |
|
|
61
|
+
| `xxlarge` | 特大 |
|
|
62
|
+
|
|
63
|
+
## 主题色
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const color = getCurrentThemeColor();
|
|
67
|
+
const vars = getCurrentThemeVars();
|
|
68
|
+
|
|
69
|
+
console.log(color, vars["--primary-color"]);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
常用导出:
|
|
73
|
+
|
|
74
|
+
| 导出 | 说明 |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `THEME_COLOR_KEY` | 主题色 storage key |
|
|
77
|
+
| `THEME_SEMANTIC_COLORS` | 语义色 |
|
|
78
|
+
| `DEFAULT_THEMES` | 内置主题色列表 |
|
|
79
|
+
| `getCurrentThemeColor()` | 读取当前主题色 |
|
|
80
|
+
| `getCurrentThemeVars()` | 生成主题色 CSS 变量 |
|
|
81
|
+
|
|
82
|
+
## 外观模式
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const appearance = getCurrentAppearance();
|
|
86
|
+
const mode = getCurrentAppearanceMode();
|
|
87
|
+
const vars = getCurrentAppearanceVars();
|
|
88
|
+
|
|
89
|
+
console.log(appearance, mode, vars["--bg-page"]);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`Appearance` 支持:
|
|
93
|
+
|
|
94
|
+
| 值 | 说明 |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `light` | 浅色模式 |
|
|
97
|
+
| `dark` | 深色模式 |
|
|
98
|
+
| `auto` | 跟随系统 |
|
|
99
|
+
|
|
100
|
+
## 排版 token
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const vars = getCurrentTypographyVars();
|
|
104
|
+
|
|
105
|
+
console.log(vars["--text-title-size"]);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
内置语义角色:
|
|
109
|
+
|
|
110
|
+
| 角色 | 用途 |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `title-lg` | 页面大标题 |
|
|
113
|
+
| `title` | 卡片或分区主标题 |
|
|
114
|
+
| `subtitle` | 次级标题 |
|
|
115
|
+
| `body` | 正文 |
|
|
116
|
+
| `desc` | 描述文字 |
|
|
117
|
+
| `caption` | 角标、时间戳等小字 |
|
|
118
|
+
|
|
119
|
+
## 切换主题
|
|
120
|
+
|
|
121
|
+
主题状态由 `useThemeStore` 管理,store 会写入 storage,`useThemePageStyle` 会响应 `scale` 和 `primaryColor` 变化。
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { useThemeStore } from "@hlw-uni/mp-vue";
|
|
125
|
+
|
|
126
|
+
const theme = useThemeStore();
|
|
127
|
+
|
|
128
|
+
theme.setScale("large");
|
|
129
|
+
theme.setTheme("#3b82f6");
|
|
130
|
+
theme.setAppearance("auto");
|
|
131
|
+
```
|
|
@@ -1,8 +1,6 @@
|
|
|
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
6
|
|
|
@@ -25,6 +23,10 @@ export function buildThemeStyle(): string {
|
|
|
25
23
|
});
|
|
26
24
|
}
|
|
27
25
|
|
|
26
|
+
function varsToStyle(vars: Record<string, string>): string {
|
|
27
|
+
return Object.entries(vars).map(([key, value]) => `${key}:${value}`).join(";") + ";";
|
|
28
|
+
}
|
|
29
|
+
|
|
28
30
|
/**
|
|
29
31
|
* 获取主题样式字符串,用于注入 <page-meta :page-style>。
|
|
30
32
|
*
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# utils 调用文档
|
|
2
|
+
|
|
3
|
+
`useUtils` 提供剪贴板、下载、保存相册、query 拼接和基础类型转换工具。
|
|
4
|
+
|
|
5
|
+
## 引入
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { useUtils } from "@hlw-uni/mp-vue";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 基础用法
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const utils = useUtils();
|
|
15
|
+
|
|
16
|
+
await utils.copy("要复制的文本");
|
|
17
|
+
const text = await utils.paste();
|
|
18
|
+
|
|
19
|
+
const qs = utils.toQuery({ id: 1, keyword: "测试" });
|
|
20
|
+
const url = utils.withQuery("/pages/search/index", qs);
|
|
21
|
+
|
|
22
|
+
const age = utils.toNumber("18", 0);
|
|
23
|
+
const enabled = utils.toBoolean("1", false);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 下载和保存
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
const res = await utils.download({
|
|
30
|
+
url: "https://example.com/a.png",
|
|
31
|
+
progress: (value, done, total) => {
|
|
32
|
+
console.log(value, done, total);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (res.ok && res.path) {
|
|
37
|
+
await utils.saveImage(res.path);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await utils.saveImageUrl("https://example.com/a.png");
|
|
41
|
+
await utils.saveVideoUrl("https://example.com/a.mp4");
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
| 方法 | 说明 |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `withQuery(url, qs)` | 为 URL 追加 query |
|
|
49
|
+
| `toQuery(data)` | 对象转 URL query |
|
|
50
|
+
| `signText(url)` | 生成签名原文,query 会排序 |
|
|
51
|
+
| `toNumber(value, defaultValue)` | 安全转数字 |
|
|
52
|
+
| `toBoolean(value, defaultValue)` | 安全转布尔 |
|
|
53
|
+
| `copy(text, tip?)` | 复制文本 |
|
|
54
|
+
| `paste()` | 读取剪贴板 |
|
|
55
|
+
| `saveImage(path)` | 保存本地图片到相册 |
|
|
56
|
+
| `saveVideo(path)` | 保存本地视频到相册 |
|
|
57
|
+
| `download(options)` | 下载文件 |
|
|
58
|
+
| `saveImageUrl(url, progress?)` | 下载远程图片并保存 |
|
|
59
|
+
| `saveVideoUrl(url, progress?)` | 下载远程视频并保存 |
|
|
60
|
+
|
|
61
|
+
## DownloadOpt
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
interface DownloadOpt {
|
|
65
|
+
url: string;
|
|
66
|
+
path?: string;
|
|
67
|
+
header?: Record<string, string>;
|
|
68
|
+
progress?: (value: number, done: number, total: number) => void;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## DownloadRes
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
interface DownloadRes {
|
|
76
|
+
ok: boolean;
|
|
77
|
+
path?: string;
|
|
78
|
+
code?: number;
|
|
79
|
+
msg?: string;
|
|
80
|
+
}
|
|
81
|
+
```
|