@hlw-uni/mp-vue 2.1.71 → 2.1.98
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/README.md +230 -386
- package/dist/app.d.ts +1 -1
- package/dist/core/index.d.ts +3 -0
- package/dist/core/{theme.d.ts → theme/index.d.ts} +6 -1
- package/dist/hlw.d.ts +1 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +834 -804
- package/dist/index.mjs +836 -806
- package/dist/utils/ad/index.d.ts +61 -0
- package/dist/{composables/utils → utils/common}/index.d.ts +1 -24
- package/dist/{composables → utils}/device/index.d.ts +7 -8
- package/dist/utils/index.d.ts +5 -0
- package/dist/{composables → utils}/navigator/index.d.ts +14 -30
- package/dist/{composables → utils}/request/client.d.ts +2 -8
- package/dist/{composables → utils}/request/index.d.ts +1 -1
- package/dist/{composables → utils}/request/service.d.ts +2 -2
- package/package.json +1 -1
- package/src/app.ts +2 -2
- package/src/components/hlw-add-mini/README.md +56 -9
- package/src/components/hlw-add-mini/index.vue +12 -9
- package/src/components/hlw-avatar-upload/index.vue +103 -0
- package/src/components/hlw-back-top/index.vue +1 -1
- package/src/components/hlw-button/index.vue +5 -16
- package/src/components/hlw-canvas/index.vue +7 -7
- package/src/components/hlw-cell/index.vue +1 -1
- package/src/components/{hlw-custom/hlw-custom.vue → hlw-custom-service/hlw-custom-service.vue} +27 -15
- package/src/components/hlw-empty/index.vue +14 -0
- package/src/components/hlw-header/index.vue +1 -1
- package/src/components/hlw-menu/index.vue +40 -37
- package/src/components/hlw-nav-bar/index.vue +23 -8
- package/src/components/hlw-nickname/index.vue +185 -0
- package/src/components/hlw-notice-bar/index.vue +23 -0
- package/src/components/hlw-page/index.vue +27 -8
- package/src/components/hlw-paging/index.vue +36 -0
- package/src/components/hlw-popup/index.vue +23 -0
- package/src/components/hlw-reward-ad/index.vue +133 -0
- package/src/components/hlw-search/index.vue +25 -0
- package/src/components/hlw-sheet/index.vue +1 -1
- package/src/components/hlw-status-bar/index.vue +113 -0
- package/src/components/hlw-tag/index.vue +22 -0
- package/src/core/index.ts +3 -0
- package/src/{composables → core}/msg/index.ts +0 -1
- package/src/{composables → core}/refs/index.ts +0 -1
- package/src/core/theme/index.ts +115 -0
- package/src/hlw.ts +1 -21
- package/src/index.ts +3 -11
- package/src/utils/ad/README.md +114 -0
- package/src/utils/ad/index.ts +234 -0
- package/src/{composables/utils → utils/common}/index.ts +1 -27
- package/src/{composables → utils}/device/index.ts +13 -21
- package/src/utils/index.ts +5 -0
- package/src/{composables → utils}/navigator/index.ts +30 -31
- package/src/{composables → utils}/request/client.ts +3 -11
- package/src/{composables → utils}/request/index.ts +1 -1
- package/src/{composables → utils}/request/service.ts +5 -6
- package/src/{composables → utils}/request/types.ts +0 -1
- package/dist/composables/ad/index.d.ts +0 -42
- package/dist/composables/index.d.ts +0 -11
- package/src/composables/ad/README.md +0 -58
- package/src/composables/ad/index.ts +0 -227
- package/src/composables/device/README.md +0 -50
- package/src/composables/index.ts +0 -38
- package/src/composables/msg/README.md +0 -79
- package/src/composables/navigator/README.md +0 -71
- package/src/composables/refs/README.md +0 -40
- package/src/composables/request/README.md +0 -124
- package/src/composables/share/README.md +0 -53
- package/src/composables/utils/README.md +0 -81
- package/src/core/theme.ts +0 -62
- /package/dist/{composables → core}/msg/index.d.ts +0 -0
- /package/dist/{composables → core}/refs/index.d.ts +0 -0
- /package/dist/{composables → core}/share/index.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/alist.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/base.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/cos.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/index.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/oss.d.ts +0 -0
- /package/dist/{composables → utils}/request/adapters/qiniu.d.ts +0 -0
- /package/dist/{composables → utils}/request/types.d.ts +0 -0
- /package/src/{composables → core}/share/index.ts +0 -0
- /package/src/{composables → utils}/request/adapters/alist.ts +0 -0
- /package/src/{composables → utils}/request/adapters/base.ts +0 -0
- /package/src/{composables → utils}/request/adapters/cos.ts +0 -0
- /package/src/{composables → utils}/request/adapters/index.ts +0 -0
- /package/src/{composables → utils}/request/adapters/oss.ts +0 -0
- /package/src/{composables → utils}/request/adapters/qiniu.ts +0 -0
|
@@ -2,10 +2,29 @@
|
|
|
2
2
|
<view :class="[theme, fontSizeClass, fontFamilyClass]">
|
|
3
3
|
<hlw-nav-bar v-if="props.isBar" :is-back="props.isBack" :title="title" :is-bar="props.isBar"></hlw-nav-bar>
|
|
4
4
|
<slot></slot>
|
|
5
|
+
<view class="h-[50rpx]"></view>
|
|
5
6
|
</view>
|
|
6
7
|
</template>
|
|
7
8
|
|
|
8
9
|
<script lang="ts" setup>
|
|
10
|
+
/**
|
|
11
|
+
* HlwPage — 页面核心容器组件
|
|
12
|
+
*
|
|
13
|
+
* 所有小程序页面的主框架容器。自动适配全局主题、字体大小和字体样式。
|
|
14
|
+
* 可以快捷集成自定义导航栏(HlwNavBar),保持整个页面结构的一致性。
|
|
15
|
+
*
|
|
16
|
+
* @props
|
|
17
|
+
* isBar - 是否显示并使用自定义导航栏,默认 false
|
|
18
|
+
* title - 自定义导航栏标题文字(在 isBar 为 true 时生效)
|
|
19
|
+
* isBack - 是否显示自定义导航栏的返回键(在 isBar 为 true 时生效),默认 false
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```vue
|
|
23
|
+
* <hlw-page is-bar is-back title="个人中心">
|
|
24
|
+
* <view>页面内容...</view>
|
|
25
|
+
* </hlw-page>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
9
28
|
import { useTheme } from "@/core";
|
|
10
29
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
11
30
|
import { ref } from "vue";
|
|
@@ -77,46 +96,46 @@ const title = ref(props.title);
|
|
|
77
96
|
Roboto,
|
|
78
97
|
Helvetica,
|
|
79
98
|
Arial,
|
|
80
|
-
sans-serif
|
|
99
|
+
sans-serif;
|
|
81
100
|
view,
|
|
82
101
|
text,
|
|
83
102
|
button,
|
|
84
103
|
input,
|
|
85
104
|
textarea {
|
|
86
|
-
font-family: inherit
|
|
105
|
+
font-family: inherit;
|
|
87
106
|
}
|
|
88
107
|
}
|
|
89
108
|
|
|
90
109
|
.font-family-sans {
|
|
91
|
-
font-family: "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif
|
|
110
|
+
font-family: "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif;
|
|
92
111
|
view,
|
|
93
112
|
text,
|
|
94
113
|
button,
|
|
95
114
|
input,
|
|
96
115
|
textarea {
|
|
97
|
-
font-family: inherit
|
|
116
|
+
font-family: inherit;
|
|
98
117
|
}
|
|
99
118
|
}
|
|
100
119
|
|
|
101
120
|
.font-family-serif {
|
|
102
|
-
font-family: "Songti SC", "STSong", "SimSun", "Georgia", serif
|
|
121
|
+
font-family: "Songti SC", "STSong", "SimSun", "Georgia", serif;
|
|
103
122
|
view,
|
|
104
123
|
text,
|
|
105
124
|
button,
|
|
106
125
|
input,
|
|
107
126
|
textarea {
|
|
108
|
-
font-family: inherit
|
|
127
|
+
font-family: inherit;
|
|
109
128
|
}
|
|
110
129
|
}
|
|
111
130
|
|
|
112
131
|
.font-family-kaiti {
|
|
113
|
-
font-family: "Kaiti SC", "STKaiti", "KaiTi", "SimKai", serif
|
|
132
|
+
font-family: "Kaiti SC", "STKaiti", "KaiTi", "SimKai", serif;
|
|
114
133
|
view,
|
|
115
134
|
text,
|
|
116
135
|
button,
|
|
117
136
|
input,
|
|
118
137
|
textarea {
|
|
119
|
-
font-family: inherit
|
|
138
|
+
font-family: inherit;
|
|
120
139
|
}
|
|
121
140
|
}
|
|
122
141
|
</style>
|
|
@@ -46,6 +46,42 @@
|
|
|
46
46
|
</template>
|
|
47
47
|
|
|
48
48
|
<script setup lang="ts">
|
|
49
|
+
/**
|
|
50
|
+
* HlwPaging — 高级分页滚动加载组件
|
|
51
|
+
*
|
|
52
|
+
* 基于 z-paging 封装,集成了系统级 HlwLoading 和 HlwEmpty 状态。
|
|
53
|
+
* 支持下拉刷新、上拉加载、自动空状态占位与错误提示展示。
|
|
54
|
+
*
|
|
55
|
+
* @props
|
|
56
|
+
* modelValue - 绑定的列表数组数据
|
|
57
|
+
* fixed - 是否固定在屏幕上,默认 false
|
|
58
|
+
* usePageScroll - 是否使用页面滚动,默认 false
|
|
59
|
+
* height - 高度样式,如 "100%"
|
|
60
|
+
* refresherEnabled - 是否开启下拉刷新,默认 true
|
|
61
|
+
* loadingMoreEnabled - 是否开启上拉加载,默认 true
|
|
62
|
+
* defaultPageSize - 默认每页大小
|
|
63
|
+
* loadingText - 加载提示文案,默认 "加载中..."
|
|
64
|
+
* emptyText - 数据为空提示文案,默认 "暂无数据"
|
|
65
|
+
* errorText - 数据加载失败提示文案,默认 "加载失败,请稍后重试"
|
|
66
|
+
* emptyImage - 自定义空状态图片地址
|
|
67
|
+
* useDefaultLoading - 是否使用内置加载状态插槽,默认 true
|
|
68
|
+
* useDefaultEmpty - 是否使用内置空状态插槽,默认 true
|
|
69
|
+
*
|
|
70
|
+
* @events
|
|
71
|
+
* update:modelValue - 更新列表数组数据时触发
|
|
72
|
+
* query - 请求新一页数据时触发 (pageNo, pageSize)
|
|
73
|
+
*
|
|
74
|
+
* @exposed
|
|
75
|
+
* pagingRef - 内部 z-paging 的 ref 实例
|
|
76
|
+
* completeByNoMore - 结束加载并判断是否还有更多数据 (list, isNoMore)
|
|
77
|
+
* completeByError - 请求出错时调用
|
|
78
|
+
* reload - 重载当前列表
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```vue
|
|
82
|
+
* <HlwPaging v-model="list" @query="fetchData" />
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
49
85
|
import { computed, ref, useSlots } from "vue";
|
|
50
86
|
import ZPaging from "z-paging/components/z-paging/z-paging.vue";
|
|
51
87
|
import type { HlwPagingRef } from "./types";
|
|
@@ -16,6 +16,29 @@
|
|
|
16
16
|
</template>
|
|
17
17
|
|
|
18
18
|
<script setup lang="ts">
|
|
19
|
+
/**
|
|
20
|
+
* HlwPopup — 基础遮罩弹窗组件
|
|
21
|
+
*
|
|
22
|
+
* 轻量级弹窗容器,支持从页面上、下、中等不同方位弹出。支持自定义圆角、头部标题及关闭按钮。
|
|
23
|
+
*
|
|
24
|
+
* @props
|
|
25
|
+
* show - 是否展示弹窗,默认 false
|
|
26
|
+
* position - 弹窗滑出方向:top / center / bottom,默认 bottom
|
|
27
|
+
* round - 是否启用圆角效果,默认 true
|
|
28
|
+
* closable - 是否展示关闭按钮,默认 true
|
|
29
|
+
* title - 弹窗顶部的标题文字
|
|
30
|
+
*
|
|
31
|
+
* @events
|
|
32
|
+
* update:show - 双向绑定显示状态时触发
|
|
33
|
+
* close - 弹窗关闭时触发
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```vue
|
|
37
|
+
* <HlwPopup v-model:show="visible" title="协议内容" position="bottom">
|
|
38
|
+
* <view>这里是协议正文内容...</view>
|
|
39
|
+
* </HlwPopup>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
19
42
|
interface Props {
|
|
20
43
|
show?: boolean;
|
|
21
44
|
position?: "bottom" | "center" | "top";
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hlw-reward-ad" @tap="handleClick">
|
|
3
|
+
<slot />
|
|
4
|
+
</view>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { ref, onMounted, watch } from "vue";
|
|
9
|
+
import { setRewardAd, showRewardAd, confirmRewardAd } from "../../utils/ad";
|
|
10
|
+
|
|
11
|
+
defineOptions({ name: "HlwRewardAd" });
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
/** 微信广告单元 ID */
|
|
15
|
+
unitId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const props = defineProps<Props>();
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits<{
|
|
21
|
+
(e: "onHandle", res: { success: boolean; isEnded: boolean; err?: any }): void;
|
|
22
|
+
}>();
|
|
23
|
+
|
|
24
|
+
// 点击锁定状态,防止连续多次点击重复触发广告
|
|
25
|
+
const isClicked = ref(false);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 提前初始化并静默加载广告实例的辅助方法。
|
|
29
|
+
*/
|
|
30
|
+
function preloadAd(id: string) {
|
|
31
|
+
if (!id) return;
|
|
32
|
+
// 异步静默加载,不使用 await 阻塞组件渲染或生命周期
|
|
33
|
+
setRewardAd(id).catch((err) => {
|
|
34
|
+
console.warn("[HlwRewardAd] Preload error:", err);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 组件挂载时,提前执行激励视频广告的初始化与加载
|
|
39
|
+
onMounted(() => {
|
|
40
|
+
preloadAd(props.unitId);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// 监听 unitId 的变化,确保广告单元 ID 动态改变时能够重新静默加载
|
|
44
|
+
watch(
|
|
45
|
+
() => props.unitId,
|
|
46
|
+
(newId) => {
|
|
47
|
+
preloadAd(newId);
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
async function playRewardAdFlow(): Promise<void> {
|
|
52
|
+
// 弹出全局模态 Loading 状态
|
|
53
|
+
let hidden = false;
|
|
54
|
+
hlw.$msg.showLoading("正在拉起广告");
|
|
55
|
+
|
|
56
|
+
// 设置 8 秒防超时定时器,如果 8 秒后还没有关闭加载提示,则强制关闭
|
|
57
|
+
const timer = setTimeout(() => {
|
|
58
|
+
hide();
|
|
59
|
+
}, 8000);
|
|
60
|
+
|
|
61
|
+
function hide() {
|
|
62
|
+
if (hidden) return;
|
|
63
|
+
hidden = true;
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
hlw.$msg.hideLoading();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
// 确保实例当前处于激活绑定状态
|
|
70
|
+
setRewardAd(props.unitId);
|
|
71
|
+
|
|
72
|
+
// 立即展示并播放广告
|
|
73
|
+
const res = await showRewardAd(hide);
|
|
74
|
+
|
|
75
|
+
// 播放流结束后(不管成功或退出),立刻关闭 Loading 状态
|
|
76
|
+
hide();
|
|
77
|
+
|
|
78
|
+
if (res.success && res.isEnded) {
|
|
79
|
+
emit("onHandle", {
|
|
80
|
+
success: true,
|
|
81
|
+
isEnded: true,
|
|
82
|
+
});
|
|
83
|
+
} else if (res.err) {
|
|
84
|
+
emit("onHandle", {
|
|
85
|
+
success: false,
|
|
86
|
+
isEnded: false,
|
|
87
|
+
err: res.err,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
// 未看完(中途退出),提示用户是否继续观看
|
|
91
|
+
const retry = await confirmRewardAd();
|
|
92
|
+
if (retry) {
|
|
93
|
+
// 如果用户点击继续观看,递归执行广告流程
|
|
94
|
+
await playRewardAdFlow();
|
|
95
|
+
} else {
|
|
96
|
+
emit("onHandle", {
|
|
97
|
+
success: false,
|
|
98
|
+
isEnded: false,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
hide();
|
|
104
|
+
console.error("[HlwRewardAd] Failed to show reward ad:", e);
|
|
105
|
+
emit("onHandle", {
|
|
106
|
+
success: false,
|
|
107
|
+
isEnded: false,
|
|
108
|
+
err: e,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function handleClick() {
|
|
114
|
+
if (isClicked.value) return;
|
|
115
|
+
if (!props.unitId) {
|
|
116
|
+
console.warn("[HlwRewardAd] unitId is required but empty.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
isClicked.value = true;
|
|
121
|
+
try {
|
|
122
|
+
await playRewardAdFlow();
|
|
123
|
+
} finally {
|
|
124
|
+
isClicked.value = false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<style scoped>
|
|
130
|
+
.hlw-reward-ad {
|
|
131
|
+
display: inline-block;
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -20,6 +20,31 @@
|
|
|
20
20
|
</template>
|
|
21
21
|
|
|
22
22
|
<script setup lang="ts">
|
|
23
|
+
/**
|
|
24
|
+
* HlwSearch — 高感官度输入搜索栏组件
|
|
25
|
+
*
|
|
26
|
+
* 规范化的小程序搜索栏输入框,支持一键清空、禁用、聚焦/失焦回调及回车直接搜索。
|
|
27
|
+
*
|
|
28
|
+
* @props
|
|
29
|
+
* modelValue - 双向绑定的输入内容
|
|
30
|
+
* placeholder - 占位符提示文本,默认 "搜索"
|
|
31
|
+
* disabled - 是否禁用输入,默认 false
|
|
32
|
+
* clearable - 是否允许一键清空输入,默认 true
|
|
33
|
+
* shape - 形状样式:square(方角) / round(圆角),默认 round
|
|
34
|
+
* background - 自定义搜索栏组件的背景色
|
|
35
|
+
*
|
|
36
|
+
* @events
|
|
37
|
+
* update:modelValue - 更新绑定内容时触发
|
|
38
|
+
* search - 点击键盘回车搜索时触发 (value)
|
|
39
|
+
* clear - 点击清除按钮时触发
|
|
40
|
+
* focus - 输入框聚焦时触发
|
|
41
|
+
* blur - 输入框失焦时触发
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```vue
|
|
45
|
+
* <HlwSearch v-model="keywords" placeholder="搜索商品" @search="onSearch" />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
23
48
|
interface Props {
|
|
24
49
|
modelValue?: string;
|
|
25
50
|
placeholder?: string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<view v-if="showHandle" class="hlw-sheet-handle" />
|
|
7
7
|
<text v-if="title" class="hlw-sheet-title">{{ title }}</text>
|
|
8
8
|
<view v-if="showClose" class="hlw-sheet-close" @tap="handleClose">
|
|
9
|
-
<
|
|
9
|
+
<span class="i-fa6-solid-xmark" />
|
|
10
10
|
</view>
|
|
11
11
|
</view>
|
|
12
12
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
class="hlw-status-bar"
|
|
4
|
+
:class="[theme, props.fixed ? 'fixed' : '', props.customClass]"
|
|
5
|
+
:style="statusBarStyle"
|
|
6
|
+
>
|
|
7
|
+
<slot></slot>
|
|
8
|
+
</view>
|
|
9
|
+
<!-- Spacer block when fixed is true to prevent layout shift -->
|
|
10
|
+
<view v-if="props.fixed && props.placeholder" :style="{ height: statusBarHeight + 'px' }"></view>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script lang="ts" setup>
|
|
14
|
+
/**
|
|
15
|
+
* hlw-status-bar — 自适应系统状态栏背景组件
|
|
16
|
+
*
|
|
17
|
+
* 自动获取设备系统状态栏高度,并应用与 hlw-nav-bar 完全一致的全局配色主题。
|
|
18
|
+
* 同时支持自定义 class 或自定义背景色/渐变色(自定义优先级最高)。
|
|
19
|
+
*
|
|
20
|
+
* @props
|
|
21
|
+
* fixed - 是否固定在顶部,默认 false
|
|
22
|
+
* placeholder - 是否生成占位高度区块(仅在 fixed 为 true 时有效),默认 true
|
|
23
|
+
* zIndex - 自定义 z-index 层级,默认 999
|
|
24
|
+
* customClass - 自定义样式类
|
|
25
|
+
* bgColor - 自定义背景颜色或渐变色(最高优先级,覆盖主题)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```vue
|
|
29
|
+
* <hlw-status-bar fixed bg-color="#ff0000" />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
import { computed } from "vue";
|
|
33
|
+
import { useTheme } from "@/core";
|
|
34
|
+
|
|
35
|
+
const { theme } = useTheme();
|
|
36
|
+
|
|
37
|
+
const props = defineProps({
|
|
38
|
+
/** 是否固定在顶部 */
|
|
39
|
+
fixed: {
|
|
40
|
+
type: Boolean,
|
|
41
|
+
default: false,
|
|
42
|
+
},
|
|
43
|
+
/** 是否生成占位高度区块(仅在 fixed 为 true 时有效,防止页面内容被遮挡) */
|
|
44
|
+
placeholder: {
|
|
45
|
+
type: Boolean,
|
|
46
|
+
default: true,
|
|
47
|
+
},
|
|
48
|
+
/** 自定义 z-index(在 fixed 为 true 时生效) */
|
|
49
|
+
zIndex: {
|
|
50
|
+
type: Number,
|
|
51
|
+
default: 999,
|
|
52
|
+
},
|
|
53
|
+
/** 自定义 CSS Class */
|
|
54
|
+
customClass: {
|
|
55
|
+
type: String,
|
|
56
|
+
default: "",
|
|
57
|
+
},
|
|
58
|
+
/** 自定义背景颜色(支持 Hex/RGB/渐变色,优先级最高) */
|
|
59
|
+
bgColor: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: "",
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const statusBarHeight: number = uni.getSystemInfoSync()?.statusBarHeight || 20;
|
|
66
|
+
|
|
67
|
+
const statusBarStyle = computed(() => {
|
|
68
|
+
const style: Record<string, any> = {
|
|
69
|
+
height: statusBarHeight + "px",
|
|
70
|
+
};
|
|
71
|
+
if (props.fixed) {
|
|
72
|
+
style.zIndex = props.zIndex;
|
|
73
|
+
}
|
|
74
|
+
if (props.bgColor) {
|
|
75
|
+
// 自定义颜色优先级最高,直接设置 background 样式覆盖 class 的 background-color
|
|
76
|
+
style.background = props.bgColor;
|
|
77
|
+
}
|
|
78
|
+
return style;
|
|
79
|
+
});
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<style lang="scss" scoped>
|
|
83
|
+
.hlw-status-bar {
|
|
84
|
+
width: 750rpx;
|
|
85
|
+
transition: background-color 0.2s ease, background 0.2s ease;
|
|
86
|
+
|
|
87
|
+
&.fixed {
|
|
88
|
+
position: fixed;
|
|
89
|
+
top: 0;
|
|
90
|
+
left: 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* 白色主题:白色状态栏 */
|
|
94
|
+
&.white-theme {
|
|
95
|
+
background-color: var(--navbar-bg-color, #ffffff);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* 简洁主题:背景色与页面全局背景色一致 */
|
|
99
|
+
&.light-theme {
|
|
100
|
+
background-color: var(--bg-page, #f8f8f8);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* 单色主题:纯主题色状态栏 */
|
|
104
|
+
&.mono-theme {
|
|
105
|
+
background-color: var(--primary-color, #3b82f6);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* 颜色主题:立体光影感的主题色渐变背景 */
|
|
109
|
+
&.color-theme {
|
|
110
|
+
background: linear-gradient(135deg, rgba(0, 0, 0, 0.15) 0%, rgba(255, 255, 255, 0.15) 100%), var(--primary-color, #3b82f6);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
</style>
|
|
@@ -11,6 +11,28 @@
|
|
|
11
11
|
</template>
|
|
12
12
|
|
|
13
13
|
<script setup lang="ts">
|
|
14
|
+
/**
|
|
15
|
+
* HlwTag — 轻量徽标标签组件
|
|
16
|
+
*
|
|
17
|
+
* 适用于标记状态、商品分类、分类标签等,支持多种色彩类型、镂空样式、圆角胶囊轮廓及可关闭动作。
|
|
18
|
+
*
|
|
19
|
+
* @props
|
|
20
|
+
* type - 标签色彩类型:primary / success / warning / danger / error / info,默认 primary
|
|
21
|
+
* plain - 是否为镂空样式,默认 false
|
|
22
|
+
* closable - 是否为可关闭标签(右侧展示 X 关闭按钮),默认 false
|
|
23
|
+
* size - 尺寸大小:small / medium,默认 medium
|
|
24
|
+
* round - 是否为圆角胶囊形状,默认 false
|
|
25
|
+
* color - 自定义背景与边框颜色(覆盖 type 样式)
|
|
26
|
+
*
|
|
27
|
+
* @events
|
|
28
|
+
* click - 点击标签时触发
|
|
29
|
+
* close - 点击关闭按钮时触发
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```vue
|
|
33
|
+
* <HlwTag type="success" plain round>已发货</HlwTag>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
14
36
|
import { computed } from "vue";
|
|
15
37
|
|
|
16
38
|
interface Props {
|
package/src/core/index.ts
CHANGED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { computed, watch, onMounted } from "vue";
|
|
2
|
+
import type { ComputedRef } from "vue";
|
|
3
|
+
import { onShow } from "@dcloudio/uni-app";
|
|
4
|
+
import {
|
|
5
|
+
useThemeStore,
|
|
6
|
+
themePresets,
|
|
7
|
+
fontSizePresets,
|
|
8
|
+
fontFamilyPresets
|
|
9
|
+
} from "../../stores/theme";
|
|
10
|
+
|
|
11
|
+
declare const uni: any;
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
themePresets,
|
|
15
|
+
type ThemePreset,
|
|
16
|
+
fontSizePresets,
|
|
17
|
+
type FontSizePreset,
|
|
18
|
+
fontFamilyPresets,
|
|
19
|
+
type FontFamilyPreset
|
|
20
|
+
} from "../../stores/theme";
|
|
21
|
+
|
|
22
|
+
// ==========================================
|
|
23
|
+
// 统一个性化外观配置 Hook (useTheme)
|
|
24
|
+
// ==========================================
|
|
25
|
+
|
|
26
|
+
export function useTheme() {
|
|
27
|
+
const store = useThemeStore();
|
|
28
|
+
|
|
29
|
+
// 主题
|
|
30
|
+
const theme: ComputedRef<string> = computed(() => store.theme);
|
|
31
|
+
|
|
32
|
+
// 辅助方法:设置系统状态栏/导航栏前景色(mono-theme 和 color-theme 设为白色,其余为黑色)
|
|
33
|
+
const updateNavbarColor = (targetTheme: string) => {
|
|
34
|
+
const isDarkTheme = ["mono-theme", "color-theme"].includes(targetTheme);
|
|
35
|
+
uni.setNavigationBarColor({
|
|
36
|
+
frontColor: isDarkTheme ? "#ffffff" : "#000000",
|
|
37
|
+
backgroundColor: isDarkTheme ? "#3b82f6" : "#ffffff",
|
|
38
|
+
fail: () => {}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// 1. 监控主题属性改变时,动态刷新
|
|
43
|
+
watch(
|
|
44
|
+
theme,
|
|
45
|
+
(newTheme) => {
|
|
46
|
+
updateNavbarColor(newTheme);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// 2. 组件/页面挂载完成时,执行一次设定
|
|
51
|
+
onMounted(() => {
|
|
52
|
+
updateNavbarColor(store.theme);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// 3. 页面显示或回退时,强行重刷前景色(try-catch 规避非 Page 的报错)
|
|
56
|
+
try {
|
|
57
|
+
onShow(() => {
|
|
58
|
+
updateNavbarColor(store.theme);
|
|
59
|
+
});
|
|
60
|
+
} catch (e) {
|
|
61
|
+
// 忽略非 Page 组件的绑定失败
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 4. 在 setup 初始化同步阶段以最快速度设定一次,尽可能规避生命周期滞后导致的闪烁
|
|
65
|
+
updateNavbarColor(store.theme);
|
|
66
|
+
|
|
67
|
+
// 字体大小
|
|
68
|
+
const fontSize: ComputedRef<string> = computed(() => store.fontSize);
|
|
69
|
+
const fontSizeClass: ComputedRef<string> = computed(() => {
|
|
70
|
+
const found = fontSizePresets.find((p) => p.id === store.fontSize);
|
|
71
|
+
return found ? found.class : "font-size-standard";
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// 字体样式
|
|
75
|
+
const fontFamily: ComputedRef<string> = computed(() => store.fontFamily);
|
|
76
|
+
const fontFamilyClass: ComputedRef<string> = computed(() => {
|
|
77
|
+
const found = fontFamilyPresets.find((p) => p.id === store.fontFamily);
|
|
78
|
+
return found ? found.class : "font-family-system";
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// 动作方法
|
|
82
|
+
function setFontSize(size: string): void {
|
|
83
|
+
store.setFontSize(size);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function setFontFamily(font: string): void {
|
|
87
|
+
store.setFontFamily(font);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
theme,
|
|
92
|
+
fontSize,
|
|
93
|
+
fontSizeClass,
|
|
94
|
+
setFontSize,
|
|
95
|
+
fontFamily,
|
|
96
|
+
fontFamilyClass,
|
|
97
|
+
setFontFamily,
|
|
98
|
+
store,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 首次打开小程序时,初始化默认的主题配色
|
|
104
|
+
* @param defaultTheme 默认主题 ID,默认为 "mono-theme"
|
|
105
|
+
*/
|
|
106
|
+
export function initTheme(defaultTheme = "mono-theme"): void {
|
|
107
|
+
const hasCachedTheme = uni.getStorageSync("theme");
|
|
108
|
+
if (!hasCachedTheme) {
|
|
109
|
+
const store = useThemeStore();
|
|
110
|
+
const validThemes = themePresets.map((t) => t.id);
|
|
111
|
+
if (validThemes.includes(defaultTheme)) {
|
|
112
|
+
store.theme = defaultTheme;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
package/src/hlw.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* hlw - 全局命名空间工厂
|
|
3
|
-
* 提供 $msg、$device、$request、$utils 的统一访问入口。
|
|
4
|
-
*/
|
|
5
|
-
import { useMsg } from '@/composables/msg';
|
|
6
|
-
import { useDevice, type DeviceInfo } from '@/composables/device';
|
|
7
|
-
import { useRequest } from '@/composables/request';
|
|
8
|
-
import { useUtils } from '@/composables/utils';
|
|
1
|
+
import { useMsg } from '@/core/msg';
|
|
9
2
|
|
|
10
3
|
/**
|
|
11
4
|
* 全局 hlw 实例接口定义,聚合了框架的核心能力。
|
|
@@ -13,16 +6,9 @@ import { useUtils } from '@/composables/utils';
|
|
|
13
6
|
export interface HlwInstance {
|
|
14
7
|
/** 统一的消息提示与模态弹窗管理模块 */
|
|
15
8
|
$msg: ReturnType<typeof useMsg>;
|
|
16
|
-
/** 当前运行设备的详细系统信息 */
|
|
17
|
-
$device: DeviceInfo;
|
|
18
|
-
/** 全局配置的统一 HTTP 请求实例 */
|
|
19
|
-
$request: ReturnType<typeof useRequest>;
|
|
20
|
-
/** 聚合的常用小程序公共工具函数 */
|
|
21
|
-
$utils: ReturnType<typeof useUtils>;
|
|
22
9
|
}
|
|
23
10
|
|
|
24
11
|
let _msg: ReturnType<typeof useMsg> | null = null;
|
|
25
|
-
let _utils: ReturnType<typeof useUtils> | null = null;
|
|
26
12
|
|
|
27
13
|
/**
|
|
28
14
|
* 全局单例 `hlw` 实例,各核心模块在首次读取时延迟初始化并缓存。
|
|
@@ -30,11 +16,5 @@ let _utils: ReturnType<typeof useUtils> | null = null;
|
|
|
30
16
|
export const hlw: HlwInstance = {
|
|
31
17
|
/** 延迟创建消息提示实例。 */
|
|
32
18
|
get $msg() { return (_msg ??= useMsg()); },
|
|
33
|
-
/** 延迟读取并缓存设备信息。 */
|
|
34
|
-
get $device() { return useDevice().info; },
|
|
35
|
-
/** 复用全局请求实例。 */
|
|
36
|
-
$request: useRequest(),
|
|
37
|
-
/** 延迟创建通用工具实例。 */
|
|
38
|
-
get $utils() { return (_utils ??= useUtils()); },
|
|
39
19
|
};
|
|
40
20
|
|
package/src/index.ts
CHANGED
|
@@ -8,17 +8,9 @@
|
|
|
8
8
|
* UI 组件(hlw-page / hlw-button / hlw-ad 等)走 easycom 自动注册,不在这里 export。
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
export * from "./
|
|
13
|
-
export
|
|
14
|
-
useTheme,
|
|
15
|
-
themePresets,
|
|
16
|
-
type ThemePreset,
|
|
17
|
-
fontFamilyPresets,
|
|
18
|
-
type FontFamilyPreset,
|
|
19
|
-
fontSizePresets,
|
|
20
|
-
type FontSizePreset
|
|
21
|
-
} from "./core/theme";
|
|
11
|
+
// Core / 工具
|
|
12
|
+
export * from "./core";
|
|
13
|
+
export * from "./utils";
|
|
22
14
|
|
|
23
15
|
// 类型
|
|
24
16
|
export type { HlwMenuItem } from "./components/hlw-menu/types";
|