@hlw-uni/mp-vue 2.1.59 → 2.1.69

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 (38) hide show
  1. package/README.md +388 -213
  2. package/dist/composables/index.d.ts +0 -8
  3. package/dist/composables/request/service.d.ts +2 -6
  4. package/dist/core/index.d.ts +1 -0
  5. package/dist/core/theme.d.ts +21 -0
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +113 -367
  8. package/dist/index.mjs +113 -367
  9. package/dist/stores/index.d.ts +1 -0
  10. package/dist/stores/theme.d.ts +26 -55
  11. package/package.json +1 -1
  12. package/src/components/hlw-add-mini/index.vue +147 -77
  13. package/src/components/hlw-avatar/index.vue +28 -20
  14. package/src/components/hlw-card-header/index.vue +3 -0
  15. package/src/components/hlw-cell/index.vue +6 -0
  16. package/src/components/hlw-custom/hlw-custom.vue +6 -5
  17. package/src/components/hlw-menu/index.vue +9 -3
  18. package/src/components/hlw-nav-bar/index.vue +181 -0
  19. package/src/components/hlw-page/index.vue +75 -105
  20. package/src/composables/index.ts +1 -31
  21. package/src/composables/request/service.ts +10 -3
  22. package/src/core/index.ts +1 -0
  23. package/src/core/theme.ts +62 -0
  24. package/src/env.d.ts +8 -0
  25. package/src/index.ts +10 -4
  26. package/src/stores/index.ts +1 -0
  27. package/src/stores/theme.ts +113 -101
  28. package/dist/composables/theme/appearance.d.ts +0 -55
  29. package/dist/composables/theme/font.d.ts +0 -32
  30. package/dist/composables/theme/index.d.ts +0 -46
  31. package/dist/composables/theme/palette.d.ts +0 -37
  32. package/dist/composables/theme/typography.d.ts +0 -41
  33. package/src/composables/theme/README.md +0 -131
  34. package/src/composables/theme/appearance.ts +0 -129
  35. package/src/composables/theme/font.ts +0 -95
  36. package/src/composables/theme/index.ts +0 -89
  37. package/src/composables/theme/palette.ts +0 -117
  38. package/src/composables/theme/typography.ts +0 -90
package/README.md CHANGED
@@ -1,63 +1,110 @@
1
1
  # @hlw-uni/mp-vue
2
2
 
3
- > hlw-uni Vue 组件库 — 供 uni-app 小程序业务方使用的 UI 组件集合
3
+ <p align="center">
4
+ <img src="https://img.shields.io/badge/version-2.1.59-blue.svg" alt="Version">
5
+ <img src="https://img.shields.io/badge/vue-3.x-emerald.svg" alt="Vue 3">
6
+ <img src="https://img.shields.io/badge/typescript-supported-blue.svg" alt="TypeScript">
7
+ <img src="https://img.shields.io/badge/platform-uni--app-red.svg" alt="uni-app">
8
+ </p>
4
9
 
5
- 基于 Vue 3 + TypeScript 构建,面向 uni-app 多端小程序(微信、抖音等)场景,由 uni-app 编译器适配各平台原生组件。
10
+ > **hlw-uni 小程序运行时核心组件与工具包**
11
+ > 聚合了 Vue 3 UI 组件库、高精简主题控制、网络请求封装、常用 Composables 工具集。从 `2.0` 起,已全面合并原 `@hlw-uni/mp-core` 的全部能力,实现业务方一处 import,全场景覆盖。
6
12
 
7
- ## 特性
13
+ ---
14
+
15
+ ## 🚀 特性
8
16
 
9
- - 基于 Vue 3 Composition API + `<script setup>`
10
- - 完整的 TypeScript 类型定义
11
- - 多端兼容(微信小程序 / 抖音小程序等)
12
- - Tree-shaking 友好,按需引入
13
- - 轻量、零样式侵入
17
+ - 💪 **现代化架构** — 基于 Vue 3 Composition API + `<script setup>` 构建。
18
+ - 📐 **完整类型系统** — 100% 采用 TypeScript 编写,提供极佳的类型推导与开发体验。
19
+ - 📱 **多端小程序适配** — 面向 uni-app 多端场景(微信、抖音、支付宝等),完美兼容宿主原生组件。
20
+ - 🎨 **弹性主题能力** — 极简而强大的 CSS 变量主题方案,支持页面级和应用级自由注入与重叠扩展。
21
+ - 🧩 **按需引入 & 零体积负担** — 支持 uni-app `easycom` 自动按需引入,配合 Tree-shaking,业务产物小而美。
22
+ - 🛠️ **一键式开发基建** — 封装了消息、路由、分享、系统设备、请求、高级上传及 BaseService 服务基类,开箱即用。
23
+
24
+ ---
14
25
 
15
- ## 安装
26
+ ## 📦 安装与配置
27
+
28
+ ### 1. 安装组件库
16
29
 
17
30
  ```bash
18
- npm install @hlw-uni/mp-vue
19
- # 或
20
31
  pnpm add @hlw-uni/mp-vue
32
+ # 或者使用 npm / yarn
33
+ npm install @hlw-uni/mp-vue
21
34
  ```
22
35
 
23
- ### Peer Dependencies
36
+ > [!NOTE]
37
+ > **Peer Dependencies**
38
+ > - `vue >= 3.4.0`
39
+ > - `pinia >= 2.0.0` (如需使用全局 App 上下文及状态)
40
+
41
+ ### 2. easycom 组件自动注册
42
+
43
+ 在业务项目的 `pages.json` 中配置 `easycom`,即可在页面中直接使用 `hlw-` 开头的全部 UI 组件,**无需手动 `import` 和注册**:
44
+
45
+ ```json
46
+ {
47
+ "easycom": {
48
+ "autoscan": true,
49
+ "custom": {
50
+ "^hlw-(.*)": "@hlw-uni/mp-vue/src/components/hlw-$1/index.vue"
51
+ }
52
+ },
53
+ "pages": [
54
+ // ...
55
+ ]
56
+ }
57
+ ```
24
58
 
25
- - `vue >= 3.4.0`
59
+ ---
26
60
 
27
- ### 依赖
61
+ ## 🛠️ 全局应用入口 & `hlw` 命名空间
28
62
 
29
- - `@hlw-uni/mp-core` 共享核心工具
63
+ ### 1. 引导初始化 `useApp()`
30
64
 
31
- ## 使用
65
+ 在小程序的 `main.ts` 或 `main.js` 中收敛并初始化 Vue 实例:
32
66
 
33
67
  ```ts
34
- import { HlwAd, HlwAvatar, HlwEmpty, HlwLoading, HlwMenuList } from '@hlw-uni/mp-vue';
35
- import type { MenuItem, HlwPagingRef } from '@hlw-uni/mp-vue';
36
- ```
68
+ import { useApp } from '@hlw-uni/mp-vue';
69
+ import { createPinia } from 'pinia';
70
+ import App from './App.vue';
37
71
 
38
- 可在页面或组件中直接注册并使用:
72
+ const app = useApp();
39
73
 
40
- ```vue
41
- <script setup lang="ts">
42
- import { HlwEmpty, HlwLoading } from '@hlw-uni/mp-vue';
43
- </script>
74
+ // 注册插件
75
+ app.use(createPinia());
44
76
 
45
- <template>
46
- <HlwLoading text="加载中..." />
47
- <HlwEmpty text="暂无数据" />
48
- </template>
77
+ // 生成符合 uni-app 约定的 createApp 入口
78
+ export const createApp = app.install(App);
49
79
  ```
50
80
 
51
- ## 主题能力
81
+ ### 2. 全局命名空间单例 `hlw`
52
82
 
53
- `mp-vue` 内置了基础主题能力,`useThemePageStyle()` 会返回一组可直接挂到页面根节点上的 CSS 变量样式。
83
+ `hlw` 命名空间聚合了框架最核心的工具服务,您可以通过全局或导入的形式方便地访问它们:
54
84
 
55
- 当前内置变量主要包括:
85
+ ```ts
86
+ import { hlw } from '@hlw-uni/mp-vue';
56
87
 
57
- - 主题色:`--primary-color`、`--primary-light`、`--primary-dark`
58
- - 字体档位:`--font-xs`、`--font-sm`、`--font-base`、`--font-md`、`--font-lg`、`--font-xl`
88
+ // 1. $msg 消息通知
89
+ hlw.$msg.toast("操作成功");
59
90
 
60
- ### 基础用法
91
+ // 2. $device 系统设备信息
92
+ console.log(hlw.$device.brand, hlw.$device.platform);
93
+
94
+ // 3. $request HTTP 客户端
95
+ const res = await hlw.$request.get("/config");
96
+
97
+ // 4. $utils 公共工具箱
98
+ hlw.$utils.copy("复制的文本");
99
+ ```
100
+
101
+ ---
102
+
103
+ ## 🎨 样式与主题能力
104
+
105
+ `mp-vue` 内置了基础主题驱动。推荐使用 `useThemePageStyle()` 组合式 API,它会返回一组挂载在页面根节点上的标准化 CSS 变量样式。
106
+
107
+ ### 1. 基础用法
61
108
 
62
109
  ```vue
63
110
  <script setup lang="ts">
@@ -67,8 +114,9 @@ const { themePageStyle } = useThemePageStyle();
67
114
  </script>
68
115
 
69
116
  <template>
70
- <hlw-page :style="themePageStyle" title="首页">
71
- <view class="demo-card">主题演示</view>
117
+ <!-- 将主题变量样式挂载在最外层容器 -->
118
+ <hlw-page :style="themePageStyle" title="主题演示">
119
+ <view class="demo-card">体验主题色</view>
72
120
  </hlw-page>
73
121
  </template>
74
122
 
@@ -77,13 +125,14 @@ const { themePageStyle } = useThemePageStyle();
77
125
  color: var(--primary-color);
78
126
  background: var(--primary-light);
79
127
  font-size: var(--font-base);
128
+ border-radius: var(--radius-md);
80
129
  }
81
130
  </style>
82
131
  ```
83
132
 
84
- ### 叠加项目自定义主题变量
133
+ ### 2. 自由追加 / 覆盖自定义主题变量
85
134
 
86
- 如果业务项目还需要自己的主题参数,推荐在 `themePageStyle` 的基础上继续追加,而不是直接修改组件库源码。
135
+ 不推荐直接修改组件库源码,您可以在返回的变量基础上动态拼接项目或页面级别的专属主题参数:
87
136
 
88
137
  ```vue
89
138
  <script setup lang="ts">
@@ -99,243 +148,324 @@ const pageStyle = computed(() => {
99
148
  themePageStyle.value,
100
149
  `--page-bg: ${themeStore.primaryColor}10`,
101
150
  `--card-shadow: 0 12rpx 40rpx ${themeStore.primaryColor}22`,
102
- `--header-gradient: linear-gradient(135deg, ${themeStore.primaryColor}, #0f172a)`,
103
151
  `--brand-text-color: #0f172a`,
104
152
  ].join(";");
105
153
  });
106
154
  </script>
107
155
 
108
156
  <template>
109
- <hlw-page :style="pageStyle" title="首页">
110
- <view class="hero">项目自定义主题</view>
157
+ <hlw-page :style="pageStyle" title="自定义主题">
158
+ <view class="custom-card">高度扩展</view>
111
159
  </hlw-page>
112
160
  </template>
161
+ ```
113
162
 
114
- <style scoped lang="scss">
115
- .hero {
116
- background: var(--header-gradient);
117
- box-shadow: var(--card-shadow);
118
- color: var(--brand-text-color);
119
- }
120
- </style>
163
+ ---
164
+
165
+ ## ⚡ 核心 Composables (工具与服务封装)
166
+
167
+ ### 💬 消息提示 — `useMsg()`
168
+
169
+ 统一且高度简化的 Toast、Loading 与原生模态弹窗。
170
+
171
+ ```ts
172
+ import { useMsg } from '@hlw-uni/mp-vue';
173
+
174
+ const msg = useMsg();
175
+
176
+ // 1. Toast 轻提示
177
+ msg.toast("普通消息提示");
178
+ msg.success("保存成功");
179
+ msg.error("提交失败");
180
+
181
+ // 2. Loading 等待框 (带透明防穿透遮罩)
182
+ msg.showLoading("数据加载中...");
183
+ // 异步操作结束后关闭
184
+ msg.hideLoading();
185
+
186
+ // 3. Promise 风格确认对话框
187
+ const confirmDelete = async () => {
188
+ const isOk = await msg.confirm({
189
+ title: "高危操作",
190
+ content: "确定要彻底删除该项目吗?",
191
+ confirmColor: "#ef4444"
192
+ });
193
+ if (isOk) {
194
+ // 执行删除...
195
+ }
196
+ };
121
197
  ```
122
198
 
123
- ### 推荐做法
199
+ ### 🗺️ 路由跳转 — `useNavigate()`
124
200
 
125
- 当项目里有较多业务主题变量时,建议再封装一层自己的组合式函数,例如 `useAppThemeStyle()`,统一输出:
201
+ 封装了小程序的各类页面跳转,自带安全的异常捕获和提示,支持打开外部小程序。
126
202
 
127
- - `mp-vue` 基础变量
128
- - 项目自定义变量
129
- - 页面级视觉变量
203
+ ```ts
204
+ import { useNavigate } from '@hlw-uni/mp-vue';
205
+
206
+ const router = useNavigate();
130
207
 
131
- 这样可以保持组件库主题和业务主题解耦,后续升级 `mp-vue` 时也更稳定。
208
+ // 基础路由跳转 (保留当前页)
209
+ router.to("/pages/detail/index?id=100");
132
210
 
133
- ## 组件
211
+ // 页面重定向 (关闭当前页)
212
+ router.redirect("/pages/login/index");
134
213
 
135
- ### HlwAd 广告组件
214
+ // 切换 TabBar 页面
215
+ router.tab("/pages/mine/index");
136
216
 
137
- 对小程序原生 `<ad>` 的封装,支持信息流 / Banner 广告。
217
+ // 干净重启 (关闭所有页面)
218
+ router.reLaunch("/pages/index/index");
138
219
 
139
- **Props**
220
+ // 返回上一页
221
+ router.back();
222
+ // 返回指定层级
223
+ router.back(2);
140
224
 
141
- | 属性 | 类型 | 必填 | 说明 |
142
- | --- | --- | --- | --- |
143
- | `unitId` | `string` | 是 | 广告单元 ID(在各平台广告后台申请) |
225
+ // 跳转到其他小程序
226
+ router.miniProgram("wx_appid_xxxxx", {
227
+ path: "pages/home/index",
228
+ envVersion: "release"
229
+ });
230
+ ```
144
231
 
145
- **Events**
232
+ ### 📤 微信分享 — `useShare()`
146
233
 
147
- | 事件 | 说明 |
148
- | --- | --- |
149
- | `load` | 广告加载成功 |
150
- | `close` | 用户关闭广告 |
151
- | `error` | 加载/展示失败,携带 `{ errCode, errMsg }` |
234
+ 优雅地在 `<script setup>` 中配置小程序卡片和朋友圈分享:
152
235
 
153
236
  ```vue
154
- <HlwAd unit-id="adunit-xxx" @load="onLoad" @error="onError" />
237
+ <script setup lang="ts">
238
+ import { useShare } from "@hlw-uni/mp-vue";
239
+
240
+ // 直接在 setup 阶段声明,将自动接管页面分享按钮及右上角菜单
241
+ useShare({
242
+ title: "推荐你体验这个超棒的小程序!",
243
+ path: "/pages/index/index?from=share",
244
+ imageUrl: "https://example.com/share-cover.png"
245
+ });
246
+ </script>
155
247
  ```
156
248
 
157
- ---
249
+ ### 🌐 网络请求 — `useRequest()` & `BaseService`
158
250
 
159
- ### HlwAvatar — 头像
251
+ 强大的请求库,完美适配拦截器模式与面向服务的 `BaseService` 设计模式。
160
252
 
161
- 支持图片头像,加载失败或未传 `src` 时降级显示首字母占位。
253
+ ```ts
254
+ import { useRequest, BaseService, ServicePrefix, ServiceNamespace } from "@hlw-uni/mp-vue";
162
255
 
163
- **Props**
256
+ const request = useRequest();
164
257
 
165
- | 属性 | 类型 | 默认 | 说明 |
166
- | --- | --- | --- | --- |
167
- | `src` | `string` | — | 头像图片地址 |
168
- | `name` | `string` | — | 用户名(首字母占位) |
169
- | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸 |
258
+ // 1. 配置全局参数
259
+ request.setBaseURL("https://api.example.com");
170
260
 
171
- ```vue
172
- <HlwAvatar :src="user.avatar" :name="user.name" size="large" />
261
+ // 2. 注册拦截器
262
+ const cancelReq = request.onRequest((config) => {
263
+ config.headers = {
264
+ ...config.headers,
265
+ "Authorization": `Bearer ${uni.getStorageSync("token")}`,
266
+ };
267
+ return config;
268
+ });
269
+
270
+ // 3. 请求接口示例
271
+ interface UserProfile {
272
+ nickname: string;
273
+ avatar: string;
274
+ }
275
+ const profile = await request.get<UserProfile>("/user/profile");
276
+
277
+ // 4. 面向服务封装 (BaseService)
278
+ @ServicePrefix("api")
279
+ @ServiceNamespace("member")
280
+ class MemberService extends BaseService {
281
+ getProfile() {
282
+ return this.get<UserProfile>("/profile"); // 自动拼接成 /api/member/profile
283
+ }
284
+ }
285
+
286
+ export const memberService = new MemberService();
173
287
  ```
174
288
 
175
289
  ---
176
290
 
177
- ### HlwEmpty 空状态
291
+ ## 🧩 核心 UI 组件库说明
178
292
 
179
- **Props**
293
+ `@hlw-uni/mp-vue` 内置了多达 27 个高频易用组件。以下重点介绍核心高频组件的 API 与用法。
180
294
 
181
- | 属性 | 类型 | 默认 | 说明 |
182
- | --- | --- | --- | --- |
183
- | `text` | `string` | `'暂无数据'` | 提示文案 |
184
- | `image` | `string` | — | 自定义占位图,未传时显示默认图标 |
295
+ ### 🏢 1. 页面容器组件 `hlw-page`
185
296
 
186
- **Slots**
297
+ 所有页面的根容器,支持自定义页头、自定义页脚、完美控制滚动区域,并通过 `provide` 驱动子组件(如 `hlw-back-top`)。
187
298
 
188
- - `default` — 自定义底部内容(如操作按钮)
299
+ #### Props
300
+
301
+ | 属性名 | 类型 | 默认值 | 说明 |
302
+ | :--- | :--- | :--- | :--- |
303
+ | `title` | `string` | `""` | 页面标题,设置后渲染默认页头 `hlw-header` |
304
+ | `isBack` | `boolean` | `false` | 是否显示返回按钮 |
305
+ | `bgClass` | `string` | `""` | 传递给 `hlw-header` 的背景 class |
306
+ | `bodyClass` | `string \| object \| array` | `""` | 内层 body 的 class,常用于设置 flex 或 gap 间距 |
307
+ | `bodyStyle` | `string \| object` | `""` | 内层 body 的自定义样式 |
308
+
309
+ #### 示例
189
310
 
190
311
  ```vue
191
- <HlwEmpty text="还没有任何记录">
192
- <button @click="refresh">刷新</button>
193
- </HlwEmpty>
312
+ <template>
313
+ <hlw-page title="用户设置" :is-back="true" body-class="p-4 gap-4">
314
+ <!-- 自定义页头 (可选) -->
315
+ <template #header>
316
+ <view class="custom-header">自定义头部</view>
317
+ </template>
318
+
319
+ <!-- 页面内容 -->
320
+ <view class="setting-list">
321
+ <view>选项一</view>
322
+ </view>
323
+
324
+ <!-- 底部悬浮/固定栏 (不随页面滚动) -->
325
+ <template #footer>
326
+ <view class="footer-bar">
327
+ <hlw-button block>保存修改</hlw-button>
328
+ </view>
329
+ </template>
330
+ </hlw-page>
331
+ </template>
194
332
  ```
195
333
 
196
334
  ---
197
335
 
198
- ### HlwLoading加载中
336
+ ### 🔘 2. 语义化按钮 `hlw-button`
199
337
 
200
- **Props**
338
+ 在原生按钮的基础上进行了大幅功能扩展,支持语义化配色、一键路由跳转、以及极简适配小程序的原生开放能力。
201
339
 
202
- | 属性 | 类型 | 说明 |
203
- | --- | --- | --- |
204
- | `text` | `string` | 加载文案,可选 |
340
+ #### Props
341
+
342
+ | 属性名 | 类型 | 默认值 | 说明 |
343
+ | :--- | :--- | :--- | :--- |
344
+ | `type` | `ButtonType` | `"primary"` | 按钮类型,可选 `primary \| success \| warning \| danger \| error \| info \| outline \| text \| ghost` |
345
+ | `size` | `"small" \| "medium" \| "large"` | `"medium"` | 按钮尺寸 |
346
+ | `loading` | `boolean` | `false` | 是否开启加载状态,开启后按钮禁用并展示 Spinner |
347
+ | `disabled` | `boolean` | `false` | 是否禁用按钮 |
348
+ | `block` | `boolean` | `false` | 是否独占整行(宽度 100%) |
349
+ | `round` | `boolean` | `false` | 是否为高圆角胶囊形态 |
350
+ | `icon` | `string` | `""` | 按钮图标类名 |
351
+ | `bgColor` | `string` | `""` | 自定义背景颜色(覆盖 type) |
352
+ | `textColor` | `string` | `""` | 自定义文字颜色 |
353
+ | `url` | `string` | `""` | 快捷页面跳转目标地址 |
354
+ | `navigateType` | `NavigateType` | `"navigateTo"` | 路由方式,可选 `navigateTo \| redirectTo \| switchTab \| reLaunch \| navigateBack` |
355
+ | `openType` | `string` | `""` | 小程序原生的开放动作类型,如 `share`, `contact`, `getPhoneNumber` 等 |
356
+
357
+ #### 示例
205
358
 
206
359
  ```vue
207
- <HlwLoading text="加载中..." />
360
+ <!-- 1. 基础语义按钮 -->
361
+ <hlw-button type="success" round>成功按钮</hlw-button>
362
+
363
+ <!-- 2. 加载态 -->
364
+ <hlw-button type="danger" :loading="true">提交中</hlw-button>
365
+
366
+ <!-- 3. 路由快捷跳转 -->
367
+ <hlw-button type="outline" url="/pages/mine/index" navigate-type="switchTab">去我的主页</hlw-button>
368
+
369
+ <!-- 4. 原生分享触发 -->
370
+ <hlw-button type="primary" open-type="share" icon="i-fa6-solid-share">分享给好友</hlw-button>
208
371
  ```
209
372
 
210
373
  ---
211
374
 
212
- ### HlwMenuList菜单列表
375
+ ### 📋 3. 高级菜单组件 `hlw-menu`
213
376
 
214
- 常用于"我的"页面的设置菜单。
377
+ 高度可定制的数据驱动菜单组件,支持列表模式和宫格网格模式。高度适配微信小程序的客服、获取手机号等 `openType` 功能。
215
378
 
216
- **Props**
379
+ #### Props
217
380
 
218
- | 属性 | 类型 | 必填 | 说明 |
219
- | --- | --- | --- | --- |
220
- | `items` | `MenuItem[]` | | 菜单项数组 |
381
+ | 属性名 | 类型 | 默认值 | 说明 |
382
+ | :--- | :--- | :--- | :--- |
383
+ | `items` | `HlwMenuItem[]` | `[]` | 菜单数据列表 |
384
+ | `title` | `string` | `""` | 卡片标题,有值时在菜单上方展示标题及分割线 |
385
+ | `mode` | `"list" \| "grid"` | `"list"` | 布局模式,可选列表或宫格模式 |
386
+ | `columns` | `number` | `4` | 宫格列数,仅在 `mode="grid"` 时有效 |
387
+ | `border` | `boolean` | `true` | 是否展示卡片容器外边框 |
221
388
 
222
- **MenuItem 类型**
389
+ #### `HlwMenuItem` 参数定义
223
390
 
224
391
  ```ts
225
- interface MenuItem {
226
- key: string; // 唯一标识
227
- label: string; // 显示文案
228
- icon?: string; // 图标(emoji 或字体)
229
- value?: string; // 右侧附加信息
230
- url?: string; // 点击跳转的页面路径
231
- action?: () => void; // 点击执行的函数
392
+ interface HlwMenuItem {
393
+ icon: string; // 图标 class
394
+ iconTheme?: string; // 图标色彩主题:orange, purple, wechat, blue, slate 等
395
+ label: string; // 菜单标签文案
396
+ url?: string; // 跳转链接,配置后点击自动跳转,无需绑定 click 事件
397
+ value?: string; // 右侧纯文本(仅列表模式)
398
+ tag?: string; // 右侧彩色标签/右上角徽标
399
+ tagTheme?: string; // 标签颜色:rose, orange, blue, wechat, red
400
+ tagPulse?: boolean; // 标签是否具有呼吸呼吸灯闪烁动画
401
+ loading?: boolean; // 是否展示加载状态
402
+ visible?: boolean; // 是否渲染该子项,控制动态显隐
403
+ openType?: string; // 小程序原生 open-type 动作
232
404
  }
233
405
  ```
234
406
 
235
- **Events**
236
-
237
- | 事件 | 参数 | 说明 |
238
- | --- | --- | --- |
239
- | `click` | `item: MenuItem` | 点击菜单项时触发 |
407
+ #### 示例
240
408
 
241
409
  ```vue
242
410
  <script setup lang="ts">
243
- import { HlwMenuList, type MenuItem } from '@hlw-uni/mp-vue';
411
+ import type { HlwMenuItem } from "@hlw-uni/mp-vue";
244
412
 
245
- const items: MenuItem[] = [
246
- { key: 'profile', label: '个人资料', icon: '👤', url: '/pages/profile/index' },
247
- { key: 'settings', label: '设置', icon: '⚙️', value: '已开启' },
248
- { key: 'logout', label: '退出登录', icon: '🚪', action: () => uni.showToast({ title: '已退出' }) },
413
+ const serviceMenus: HlwMenuItem[] = [
414
+ { icon: "i-fa6-solid-user", label: "个人资料", url: "/pages/profile/index", iconTheme: "blue" },
415
+ { icon: "i-fa6-solid-bell", label: "系统通知", value: "未读 3 条", iconTheme: "orange", tag: "HOT", tagPulse: true },
416
+ { icon: "i-fa6-solid-headset", label: "在线客服", openType: "contact", iconTheme: "wechat" },
417
+ { icon: "i-fa6-solid-gear", label: "设置中心", url: "/pages/setting/index", iconTheme: "slate" },
249
418
  ];
250
419
  </script>
251
420
 
252
421
  <template>
253
- <HlwMenuList :items="items" @click="onMenuClick" />
254
- </template>
255
- ```
256
-
257
- ## 开发
258
-
259
- ```bash
260
- # 构建
261
- npm run build
262
-
263
- # 监听构建(开发模式)
264
- npm run dev
265
- ```
422
+ <!-- 列表模式 -->
423
+ <hlw-menu title="我的服务" :items="serviceMenus" />
266
424
 
267
- 构建产物输出到 `dist/`:
268
-
269
- - `dist/index.mjs` — ES Module
270
- - `dist/index.js` — CommonJS
271
- - `dist/index.d.ts` — TypeScript 类型定义
272
-
273
- ## 项目结构
274
-
275
- ```
276
- mp-vue/
277
- ├── src/
278
- │ ├── components/
279
- │ │ ├── hlw-ad/
280
- │ │ ├── hlw-avatar/
281
- │ │ ├── hlw-empty/
282
- │ │ ├── hlw-loading/
283
- │ │ └── hlw-menu-list/
284
- │ └── index.ts # 统一导出入口
285
- ├── dist/ # 构建产物
286
- ├── package.json
287
- ├── tsconfig.json
288
- └── vite.config.ts
425
+ <!-- 宫格模式 (4列) -->
426
+ <hlw-menu mode="grid" :columns="4" :items="serviceMenus" class="mt-4" />
427
+ </template>
289
428
  ```
290
429
 
291
- ## HlwPaging
292
-
293
- 基于 `z-paging` 的包装组件。保留 `z-paging` 原始 props、事件和大部分插槽,同时默认接入 `hlw-loading` 和 `hlw-empty` 作为加载态与空态展示。
430
+ ---
294
431
 
295
- **额外 Props**
432
+ ### 📄 4. 分页滚动包装容器 — `hlw-paging`
296
433
 
297
- | 属性 | 类型 | 默认值 | 说明 |
298
- | --- | --- | --- | --- |
299
- | `loadingText` | `string` | `'加载中...'` | 默认 loading 文案 |
300
- | `emptyText` | `string` | `'暂无数据'` | 默认空态文案 |
301
- | `errorText` | `string` | `'加载失败,请稍后重试'` | 默认失败文案 |
302
- | `emptyImage` | `string` | `''` | 自定义空态图片 |
303
- | `useDefaultLoading` | `boolean` | `true` | 是否启用默认 loading 插槽 |
304
- | `useDefaultEmpty` | `boolean` | `true` | 是否启用默认 empty 插槽 |
434
+ 基于优秀的 `z-paging` 深度封装,极简整合了主题加载态(`hlw-loading`)和空状态(`hlw-empty`),提供更加一体化和顺滑的无缝滚动加载体验。
305
435
 
306
- **插槽**
436
+ #### Props
307
437
 
308
- - 继续支持 `z-paging` 的原始插槽,如 `loading`、`empty`、`refresher`、`top`、`bottom`
309
- - 额外支持 `empty-extra`,用于在默认空态下方插入自定义内容
438
+ | 属性名 | 类型 | 默认值 | 说明 |
439
+ | :--- | :--- | :--- | :--- |
440
+ | `loadingText` | `string` | `"加载中..."` | 加载提示文案 |
441
+ | `emptyText` | `string` | `"暂无数据"` | 空状态提示文案 |
442
+ | `emptyImage` | `string` | `""` | 自定义空状态图片地址 |
443
+ | `useDefaultLoading` | `boolean` | `true` | 是否使用内置的 `hlw-loading` 插槽 |
444
+ | `useDefaultEmpty` | `boolean` | `true` | 是否使用内置的 `hlw-empty` 插槽 |
310
445
 
311
- **Ref 类型**
312
-
313
- ```ts
314
- import type { HlwPagingRef } from '@hlw-uni/mp-vue';
315
- ```
316
-
317
- **基础示例**
446
+ #### 示例
318
447
 
319
448
  ```vue
320
449
  <script setup lang="ts">
321
- import { ref } from 'vue';
322
- import type { HlwPagingRef } from '@hlw-uni/mp-vue';
450
+ import { ref } from "vue";
451
+ import type { HlwPagingRef } from "@hlw-uni/mp-vue";
323
452
 
324
- interface ListItem {
453
+ interface Article {
325
454
  id: number;
326
455
  title: string;
327
456
  }
328
457
 
329
- const paging = ref<HlwPagingRef<ListItem> | null>(null);
330
- const dataList = ref<ListItem[]>([]);
331
-
332
- const queryList = async (pageNo: number, pageSize: number) => {
333
- const list = Array.from({ length: pageSize }, (_, index) => ({
334
- id: (pageNo - 1) * pageSize + index + 1,
335
- title: `第 ${pageNo} 页数据 ${index + 1}`,
336
- }));
337
-
338
- paging.value?.completeByNoMore(list, pageNo >= 3);
458
+ const paging = ref<HlwPagingRef<Article> | null>(null);
459
+ const dataList = ref<Article[]>([]);
460
+
461
+ const onQuery = async (pageNo: number, pageSize: number) => {
462
+ try {
463
+ const res = await fetchArticleList({ page: pageNo, limit: pageSize });
464
+ // 渲染并控制页数判定
465
+ paging.value?.completeByNoMore(res.list, res.list.length < pageSize);
466
+ } catch (err) {
467
+ paging.value?.completeByError(err);
468
+ }
339
469
  };
340
470
  </script>
341
471
 
@@ -343,40 +473,85 @@ const queryList = async (pageNo: number, pageSize: number) => {
343
473
  <hlw-paging
344
474
  ref="paging"
345
475
  v-model="dataList"
346
- @query="queryList"
347
- loading-text="正在同步数据"
348
- empty-text="还没有任何记录"
476
+ loading-text="同步文章列表中"
477
+ empty-text="还没有发表任何文章"
478
+ @query="onQuery"
349
479
  >
350
- <view v-for="item in dataList" :key="item.id" class="demo-row">
480
+ <view v-for="item in dataList" :key="item.id" class="article-item p-4 border-b">
351
481
  {{ item.title }}
352
482
  </view>
353
483
  </hlw-paging>
354
484
  </template>
355
485
  ```
356
486
 
357
- **自定义空态**
487
+ ---
358
488
 
359
- ```vue
360
- <hlw-paging v-model="dataList" @query="queryList" :use-default-empty="false">
361
- <template #empty="{ isLoadFailed }">
362
- <hlw-empty :text="isLoadFailed ? '请求失败,请重试' : '这里暂时还是空的'" />
363
- </template>
364
- </hlw-paging>
489
+ ## 📂 27个 UI 组件完整索引
490
+
491
+ 为了使开发者了解所有可用的 UI 资产,以下是 `@hlw-uni/mp-vue` 内置的 27 个组件的完整全景列表:
492
+
493
+ | 组件目录 | 组件名称 | 适用场景及简要说明 |
494
+ | :--- | :--- | :--- |
495
+ | 🎬 `hlw-ad` | 广告展示 | 对小程序原生 `<ad>` 的封装,支持信息流/Banner广告等 |
496
+ | 📲 `hlw-add-mini` | 添加提示 | 引导用户点击小程序右上角“添加到我的小程序”的气泡提示 |
497
+ | 👤 `hlw-avatar` | 用户头像 | 支持图片头像,加载失败时自动降级渲染文字首字母占位 |
498
+ | 🔝 `hlw-back-top` | 返回顶部 | 自动监听页面滚动并展示悬浮按钮,支持平滑的一键回顶 |
499
+ | 🔘 `hlw-button` | 语义化按钮 | 支持多种语义色彩、尺寸档位、路由快捷跳转与原生开放动作 |
500
+ | 🎨 `hlw-canvas` | 海报绘制 | 用于快捷生成小程序分享海报的 Canvas 画布包装工具 |
501
+ | 📦 `hlw-card` | 卡片容器 | 带有微阴影与圆角的高质感布局容器,常用于聚合业务块 |
502
+ | 🏷️ `hlw-card-header` | 卡片头部 | 专门为卡片组件设计的标题栏,支持小装饰线条和动作插槽 |
503
+ | 🗂️ `hlw-cell` | 单元格 | 规范的列表项组件,支持图标、标题、副标题与右侧各种扩展插槽 |
504
+ | 🧩 `hlw-custom` | 自定义容器 | 统一规范的多用途自定义包装外框 |
505
+ | ➖ `hlw-divider` | 分割线 | 带文字或纯线条的排版分割线 |
506
+ | 🏜️ `hlw-empty` | 空状态 | 精美质感的空态图标及提示文案,支持挂载自定义引导动作按钮 |
507
+ | 🧭 `hlw-header` | 自定义导航栏 | 对小程序原生导航栏的完美替代,支持沉浸式状态栏与返回动作 |
508
+ | 🖼️ `hlw-image` | 增强图片 | 支持平滑过渡加载效果、支持懒加载及骨架图占位的 Image 增强版 |
509
+ | 🔄 `hlw-loading` | 加载指示器 | 统一风格的加载转圈动效及文案提示 |
510
+ | 🍔 `hlw-menu` | 多功能菜单 | 数据驱动,列表模式/宫格模式自由切换,高度适配 `openType` |
511
+ | 💬 `hlw-modal` | 模态弹窗 | 轻量的确认与提示弹窗组件 |
512
+ | 📢 `hlw-notice-bar` | 滚动通告栏 | 经典的横向滚动滚动条,用于突发通告、重要广播等 |
513
+ | 🎁 `hlw-notice-popup` | 通告弹窗 | 页面初始化时弹出的卡片式全局公告、优惠券或活动图 |
514
+ | 🏢 `hlw-page` | 页面核心骨架 | 收敛顶部导航栏、底部固定栏与中间高度自适应页面的核心基础件 |
515
+ | 📜 `hlw-paging` | 分页滚动组件 | 基于 `z-paging` 深度打通,无缝管理下拉刷新与上拉加载 |
516
+ | 🎪 `hlw-popup` | 基础弹窗 | 支持上、下、中等各种方位的轻量级弹窗蒙层容器 |
517
+ | 🔍 `hlw-search` | 搜索栏 | 高颜值的小程序搜索输入框,支持一键清空、聚焦回调等 |
518
+ | 🗃️ `hlw-sheet` | 动作面板 | 从页面底部升起的动作面板或选项操作菜单 (Action Sheet) |
519
+ | 💀 `hlw-skeleton` | 骨架屏 | 高质感微光渐变波纹效果的占位加载骨架屏 |
520
+ | 📑 `hlw-tabs` | 横向选项卡 | 自动计算高亮的切换栏,支持文字或含数字徽标的选项 |
521
+ | 🔖 `hlw-tag` | 标签 | 多种色彩、填充模式(实心、镂空)的小标签 |
522
+
523
+ ---
524
+
525
+ ## 💻 本地开发与贡献说明
526
+
527
+ 若您需要对 `@hlw-uni/mp-vue` 库进行二次开发、修补或提交贡献,可按如下流程进行:
528
+
529
+ ### 1. 启动监听式构建 (开发模式)
530
+
531
+ ```bash
532
+ pnpm dev
533
+ # 此时 vite 会监听 src 下所有文件的变动,并自动热重构同步到 dist 目录
534
+ ```
535
+
536
+ ### 2. 生成生产包
537
+
538
+ ```bash
539
+ pnpm build
540
+ # 将生成高度优化、体积极致精简的 CommonJS、ESModule 以及 .d.ts 类型声明产物
365
541
  ```
366
542
 
367
- **常用 Ref 方法**
543
+ ### 3. 构建产物结构
368
544
 
369
- - `reload(animate?)`
370
- - `refresh()`
371
- - `complete(list)`
372
- - `completeByTotal(list, total)`
373
- - `completeByNoMore(list, noMore)`
374
- - `completeByError(cause)`
375
- - `clear()`
376
- - `scrollToTop()`
545
+ ```
546
+ mp-vue/
547
+ ├── dist/
548
+ │ ├── index.js # CommonJS 格式产物
549
+ │ ├── index.mjs # ESModule 格式产物 (供现代打包器 Tree-shaking 使用)
550
+ │ └── index.d.ts # 自动生成的 TS 全量类型声明文件
551
+ ```
377
552
 
378
- 更多分页能力和原始参数可参考 `z-paging` 文档:https://z-paging.zxlee.cn
553
+ ---
379
554
 
380
- ## License
555
+ ## 📄 开源协议
381
556
 
382
- 内部组件库,仅供 hlw-uni 项目使用。
557
+ **内部私有组件库**,仅供 `hlw-uni` 项目组内部及关联方协作使用,未经授权请勿分发或公开上传至公共 NPM 镜像。