hy-app 0.5.2 → 0.5.4
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/components/hy-action-sheet/index.scss +0 -5
- package/components/hy-avatar/hy-avatar.vue +4 -3
- package/components/hy-back-top/hy-back-top.vue +10 -9
- package/components/hy-back-top/props.ts +5 -3
- package/components/hy-badge/hy-badge.vue +5 -4
- package/components/hy-badge/index.scss +0 -1
- package/components/hy-badge/props.ts +11 -4
- package/components/hy-button/hy-button.vue +5 -5
- package/components/hy-button/index.scss +9 -0
- package/components/hy-button/props.ts +11 -6
- package/components/hy-coupon/hy-coupon.vue +159 -167
- package/components/hy-coupon/index.scss +135 -516
- package/components/hy-coupon/props.ts +101 -127
- package/components/hy-coupon/typing.d.ts +147 -146
- package/components/hy-datetime-picker/props.ts +1 -3
- package/components/hy-folding-panel/props.ts +1 -1
- package/components/hy-folding-panel/typing.d.ts +0 -38
- package/components/hy-folding-panel-item/hy-folding-panel-item.vue +2 -5
- package/components/hy-folding-panel-item/index.scss +0 -8
- package/components/hy-folding-panel-item/typing.d.ts +14 -0
- package/components/hy-form-group/hy-form-group.vue +308 -511
- package/components/hy-form-group/index.scss +0 -33
- package/components/hy-form-group/props.ts +103 -13
- package/components/hy-form-group/typing.d.ts +0 -77
- package/components/hy-form-item/hy-form-item.vue +3 -3
- package/components/hy-icon/hy-icon.vue +3 -8
- package/components/hy-input/hy-input.vue +16 -10
- package/components/hy-input/index.scss +4 -0
- package/components/hy-input/props.ts +2 -2
- package/components/hy-list/props.ts +1 -1
- package/components/hy-notice-bar/hy-column-notice.vue +63 -70
- package/components/hy-notice-bar/hy-row-notice.vue +92 -110
- package/components/hy-notice-bar/index.scss +2 -4
- package/components/hy-notice-bar/props.ts +4 -1
- package/components/hy-notice-bar/typing.d.ts +2 -0
- package/components/hy-popup/hy-popup.vue +0 -1
- package/components/hy-qrcode/hy-qrcode.vue +69 -3
- package/components/hy-qrcode/index.scss +3 -3
- package/components/hy-qrcode/qrcode.js +1344 -1400
- package/components/hy-rate/hy-rate.vue +0 -1
- package/components/hy-read-more/hy-read-more.vue +1 -1
- package/components/hy-signature/hy-signature.vue +25 -22
- package/components/hy-signature/index.scss +0 -4
- package/components/hy-tabbar/hy-tabbar.vue +137 -0
- package/components/{hy-tabBar → hy-tabbar}/index.scss +30 -30
- package/components/hy-tabbar/props.ts +59 -0
- package/components/hy-tabbar/typing.d.ts +61 -0
- package/components/hy-tabbar-group/README.md +326 -0
- package/components/hy-tabbar-group/hy-tabbar-group.vue +87 -0
- package/components/hy-tabbar-group/index.scss +57 -0
- package/components/hy-tabbar-group/props.ts +78 -0
- package/components/hy-tabbar-group/typing.ts +16 -0
- package/components/hy-tabbar-item/hy-tabbar-item.vue +103 -0
- package/components/hy-tabbar-item/index.scss +43 -0
- package/components/hy-tabbar-item/props.ts +24 -0
- package/components/hy-tabbar-item/typing.ts +22 -0
- package/components/hy-tag/props.ts +8 -2
- package/components/hy-text/props.ts +8 -2
- package/components/hy-textarea/hy-textarea.vue +1 -1
- package/components/hy-textarea/index.scss +8 -7
- package/components/hy-textarea/props.ts +4 -1
- package/components/hy-toast/index.scss +2 -7
- package/components/hy-tooltip/props.ts +1 -3
- package/components/hy-upload/props.ts +1 -1
- package/components/index.ts +177 -177
- package/global.d.ts +87 -85
- package/libs/css/common.scss +0 -5
- package/libs/typing/modules/form.ts +159 -163
- package/package.json +2 -2
- package/web-types.json +1 -1
- package/components/hy-coupon/README.md +0 -133
- package/components/hy-tabBar/hy-tabBar.vue +0 -109
- package/components/hy-tabBar/props.ts +0 -13
- package/components/hy-tabBar/typing.d.ts +0 -54
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# Hy Tabbar 组件
|
|
2
|
+
|
|
3
|
+
## 介绍
|
|
4
|
+
|
|
5
|
+
Tabbar 是一个底部标签导航组件,用于在应用不同页面之间进行快速切换。支持自定义样式、图标、文字、徽章、激活状态和路由跳转等功能。
|
|
6
|
+
|
|
7
|
+
## 组件关系
|
|
8
|
+
|
|
9
|
+
- `hy-tabbar-group`: 作为容器,管理多个 tabbar-item
|
|
10
|
+
- `hy-tabbar-item`: 作为单个标签项,包含图标、文字和徽章等元素
|
|
11
|
+
|
|
12
|
+
## 引入方式
|
|
13
|
+
|
|
14
|
+
### 全局引入
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// 在 main.ts 或 index.ts 中引入
|
|
18
|
+
import { createApp } from 'vue'
|
|
19
|
+
import App from './App.vue'
|
|
20
|
+
import HyDesignUni from '@/package'
|
|
21
|
+
|
|
22
|
+
const app = createApp(App)
|
|
23
|
+
app.use(HyDesignUni)
|
|
24
|
+
app.mount('#app')
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 局部引入
|
|
28
|
+
|
|
29
|
+
```vue
|
|
30
|
+
<template>
|
|
31
|
+
<hy-tabbar-group v-model="current">
|
|
32
|
+
<hy-tabbar-item index="0" icon="home" text="首页"></hy-tabbar-item>
|
|
33
|
+
<hy-tabbar-item index="1" icon="discover" text="发现"></hy-tabbar-item>
|
|
34
|
+
</hy-tabbar-group>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { ref } from 'vue'
|
|
39
|
+
import HyTabbarGroup from '@/package/components/hy-tabbar-group/hy-tabbar-group.vue'
|
|
40
|
+
import HyTabbarItem from '@/package/components/hy-tabbar-item/hy-tabbar-item.vue'
|
|
41
|
+
|
|
42
|
+
const current = ref('0')
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## HyTabbarGroup API
|
|
47
|
+
|
|
48
|
+
### Props
|
|
49
|
+
|
|
50
|
+
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
|
51
|
+
| --- | --- | --- | --- | --- |
|
|
52
|
+
| v-model | `string \| number` | - | 是 | 当前选中项的索引 |
|
|
53
|
+
| fixed | `boolean` | `false` | 否 | 是否固定在底部 |
|
|
54
|
+
| safe-area-inset-bottom | `boolean` | `false` | 否 | 是否适配底部安全区域 |
|
|
55
|
+
| background | `string` | `#fff` | 否 | 背景色 |
|
|
56
|
+
| height | `string \| number` | `50px` | 否 | 高度 |
|
|
57
|
+
| border-style | `string` | - | 否 | 边框样式,可选值:`solid`、`dashed`、`dotted` |
|
|
58
|
+
| shadow-level | `0 \| 1 \| 2 \| 3` | `0` | 否 | 阴影等级 |
|
|
59
|
+
| active-color | `string` | `#1677ff` | 否 | 激活状态颜色 |
|
|
60
|
+
| inactive-color | `string` | `#606266` | 否 | 非激活状态颜色 |
|
|
61
|
+
| icon-size | `string \| number` | `24` | 否 | 图标大小 |
|
|
62
|
+
| fontSize | `string \| number` | `12` | 否 | 文字大小 |
|
|
63
|
+
| icon-text-space | `string \| number` | `4` | 否 | 图标与文字间距 |
|
|
64
|
+
| indicator-mode | `'none' \| 'bottom' \| 'top' \| 'full'` | `'none'` | 否 | 指示器模式 |
|
|
65
|
+
| indicator-color | `string` | `#1677ff` | 否 | 指示器颜色 |
|
|
66
|
+
| indicator-height | `string \| number` | `3px` | 否 | 指示器高度 |
|
|
67
|
+
| indicator-length | `string \| number` | `20px` | 否 | 指示器长度 |
|
|
68
|
+
| indicator-radius | `string \| number` | `4px` | 否 | 指示器圆角 |
|
|
69
|
+
| transition-duration | `string \| number` | `300` | 否 | 过渡动画时长 |
|
|
70
|
+
| customClass | `string` | - | 否 | 自定义类名 |
|
|
71
|
+
| customStyle | `object` | - | 否 | 自定义样式 |
|
|
72
|
+
| activeClass | `string` | - | 否 | 激活时的自定义类名 |
|
|
73
|
+
|
|
74
|
+
### Events
|
|
75
|
+
|
|
76
|
+
| 事件名 | 说明 | 回调参数 |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| click | 点击标签项时触发 | `index: string \| number` | 选中项的索引 |
|
|
79
|
+
| change | 选中项改变时触发 | `index: string \| number` | 选中项的索引 |
|
|
80
|
+
| active | 选中项被激活时触发 | `index: string \| number` | 选中项的索引 |
|
|
81
|
+
| update:active | 更新激活状态时触发 | `index: string \| number` | 选中项的索引 |
|
|
82
|
+
|
|
83
|
+
### Slots
|
|
84
|
+
|
|
85
|
+
| 名称 | 说明 | 子标签 |
|
|
86
|
+
| --- | --- | --- |
|
|
87
|
+
| default | 容纳 hy-tabbar-item 子组件 | `<hy-tabbar-item>` |
|
|
88
|
+
|
|
89
|
+
### Expose
|
|
90
|
+
|
|
91
|
+
| 方法名 | 说明 | 参数 |
|
|
92
|
+
| --- | --- | --- |
|
|
93
|
+
| selectItem | 选中指定标签项 | `index: string \| number` | 要选中的索引 |
|
|
94
|
+
| updateRectInfo | 更新位置信息 | - |
|
|
95
|
+
| registerTabItem | 注册标签项 | `item: object` | 标签项信息 |
|
|
96
|
+
| unregisterTabItem | 注销标签项 | `item: object` | 标签项信息 |
|
|
97
|
+
| handleClick | 处理点击事件 | `index: string \| number` | 点击的索引 |
|
|
98
|
+
|
|
99
|
+
## HyTabbarItem API
|
|
100
|
+
|
|
101
|
+
### Props
|
|
102
|
+
|
|
103
|
+
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
|
104
|
+
| --- | --- | --- | --- | --- |
|
|
105
|
+
| index | `string \| number` | - | 是 | 标签项的索引 |
|
|
106
|
+
| icon | `string` | - | 否 | 图标名称 |
|
|
107
|
+
| text | `string` | - | 否 | 文字内容 |
|
|
108
|
+
| route | `string` | - | 否 | 路由路径 |
|
|
109
|
+
| show-icon | `boolean` | `true` | 否 | 是否显示图标 |
|
|
110
|
+
| hide-text | `boolean` | `false` | 否 | 是否隐藏文字 |
|
|
111
|
+
| disabled | `boolean` | `false` | 否 | 是否禁用 |
|
|
112
|
+
| click-effect | `'none' \| 'feedback' \| 'ripple'` | `'none'` | 否 | 点击效果 |
|
|
113
|
+
| ripple-duration | `string` | `'300ms'` | 否 | 波纹动画时长 |
|
|
114
|
+
| width | `string \| number` | - | 否 | 宽度 |
|
|
115
|
+
| height | `string \| number` | - | 否 | 高度 |
|
|
116
|
+
| show-active-bg | `boolean` | `false` | 否 | 是否显示激活背景 |
|
|
117
|
+
| active-bg-color | `string` | - | 否 | 激活背景颜色 |
|
|
118
|
+
| icon-color | `string` | - | 否 | 图标颜色 |
|
|
119
|
+
| active-icon-color | `string` | - | 否 | 激活时图标颜色 |
|
|
120
|
+
| inactive-icon-color | `string` | - | 否 | 非激活时图标颜色 |
|
|
121
|
+
| text-color | `string` | - | 否 | 文字颜色 |
|
|
122
|
+
| active-text-color | `string` | - | 否 | 激活时文字颜色 |
|
|
123
|
+
| inactive-text-color | `string` | - | 否 | 非激活时文字颜色 |
|
|
124
|
+
| icon-size | `string \| number` | `24` | 否 | 图标大小 |
|
|
125
|
+
| icon-text-space | `string \| number` | `4` | 否 | 图标与文字间距 |
|
|
126
|
+
| badge | `string \| number \| null` | - | 否 | 徽章内容 |
|
|
127
|
+
| badge-offset | `[number, number]` | `[0, 0]` | 否 | 徽章偏移量 |
|
|
128
|
+
| badge-max | `number` | `99` | 否 | 徽章最大值 |
|
|
129
|
+
| badge-is-dot | `boolean` | `false` | 否 | 是否显示为点 |
|
|
130
|
+
| badge-inverted | `boolean` | `false` | 否 | 是否使用浅色背景 |
|
|
131
|
+
| badge-bg-color | `string` | `#ff4d4f` | 否 | 徽章背景色 |
|
|
132
|
+
| badge-text-color | `string` | `#fff` | 否 | 徽章文字颜色 |
|
|
133
|
+
| badge-show-zero | `boolean` | `false` | 否 | 徽章为0时是否显示 |
|
|
134
|
+
| customClass | `string` | - | 否 | 自定义类名 |
|
|
135
|
+
| customStyle | `object` | - | 否 | 自定义样式 |
|
|
136
|
+
| activeClass | `string` | - | 否 | 激活时的自定义类名 |
|
|
137
|
+
|
|
138
|
+
### Events
|
|
139
|
+
|
|
140
|
+
| 事件名 | 说明 | 回调参数 |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| click | 点击标签项时触发 | `{ index, icon, text }` | 标签项信息 |
|
|
143
|
+
| active | 标签项被激活时触发 | `index: string \| number` | 标签项索引 |
|
|
144
|
+
| change | 标签项状态改变时触发 | `index: string \| number` | 标签项索引 |
|
|
145
|
+
| update:active | 更新激活状态时触发 | `index: string \| number` | 标签项索引 |
|
|
146
|
+
|
|
147
|
+
### Slots
|
|
148
|
+
|
|
149
|
+
| 名称 | 说明 |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| default | 自定义文字内容 |
|
|
152
|
+
| icon | 自定义图标内容 |
|
|
153
|
+
|
|
154
|
+
## 使用示例
|
|
155
|
+
|
|
156
|
+
### 基础用法
|
|
157
|
+
|
|
158
|
+
```vue
|
|
159
|
+
<hy-tabbar-group v-model="current">
|
|
160
|
+
<hy-tabbar-item index="0" icon="home" text="首页"></hy-tabbar-item>
|
|
161
|
+
<hy-tabbar-item index="1" icon="discover" text="发现"></hy-tabbar-item>
|
|
162
|
+
<hy-tabbar-item index="2" icon="shopping-cart" text="购物车"></hy-tabbar-item>
|
|
163
|
+
<hy-tabbar-item index="3" icon="user" text="我的"></hy-tabbar-item>
|
|
164
|
+
</hy-tabbar-group>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 固定在底部
|
|
168
|
+
|
|
169
|
+
```vue
|
|
170
|
+
<hy-tabbar-group
|
|
171
|
+
v-model="current"
|
|
172
|
+
fixed
|
|
173
|
+
safe-area-inset-bottom
|
|
174
|
+
background="#fff"
|
|
175
|
+
border-style="solid"
|
|
176
|
+
>
|
|
177
|
+
<hy-tabbar-item index="0" icon="home" text="首页"></hy-tabbar-item>
|
|
178
|
+
<hy-tabbar-item index="1" icon="discover" text="发现"></hy-tabbar-item>
|
|
179
|
+
</hy-tabbar-group>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 添加徽章
|
|
183
|
+
|
|
184
|
+
```vue
|
|
185
|
+
<hy-tabbar-group v-model="current">
|
|
186
|
+
<hy-tabbar-item index="0" icon="home" text="首页"></hy-tabbar-item>
|
|
187
|
+
<hy-tabbar-item index="1" icon="message" text="消息" :badge="5"></hy-tabbar-item>
|
|
188
|
+
<hy-tabbar-item index="2" icon="notification" text="通知" badge-is-dot></hy-tabbar-item>
|
|
189
|
+
</hy-tabbar-group>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 自定义激活样式
|
|
193
|
+
|
|
194
|
+
```vue
|
|
195
|
+
<hy-tabbar-group
|
|
196
|
+
v-model="current"
|
|
197
|
+
active-color="#ff6b81"
|
|
198
|
+
>
|
|
199
|
+
<hy-tabbar-item
|
|
200
|
+
index="0"
|
|
201
|
+
icon="home"
|
|
202
|
+
text="首页"
|
|
203
|
+
show-active-bg
|
|
204
|
+
active-bg-color="rgba(255, 107, 129, 0.1)"
|
|
205
|
+
></hy-tabbar-item>
|
|
206
|
+
<hy-tabbar-item
|
|
207
|
+
index="1"
|
|
208
|
+
icon="discover"
|
|
209
|
+
text="发现"
|
|
210
|
+
show-active-bg
|
|
211
|
+
active-bg-color="rgba(255, 107, 129, 0.1)"
|
|
212
|
+
></hy-tabbar-item>
|
|
213
|
+
</hy-tabbar-group>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 点击效果
|
|
217
|
+
|
|
218
|
+
```vue
|
|
219
|
+
<hy-tabbar-group v-model="current">
|
|
220
|
+
<hy-tabbar-item
|
|
221
|
+
index="0"
|
|
222
|
+
icon="home"
|
|
223
|
+
text="首页"
|
|
224
|
+
click-effect="ripple"
|
|
225
|
+
></hy-tabbar-item>
|
|
226
|
+
<hy-tabbar-item
|
|
227
|
+
index="1"
|
|
228
|
+
icon="discover"
|
|
229
|
+
text="发现"
|
|
230
|
+
click-effect="feedback"
|
|
231
|
+
></hy-tabbar-item>
|
|
232
|
+
</hy-tabbar-group>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 路由跳转
|
|
236
|
+
|
|
237
|
+
```vue
|
|
238
|
+
<hy-tabbar-group v-model="current">
|
|
239
|
+
<hy-tabbar-item
|
|
240
|
+
index="0"
|
|
241
|
+
icon="home"
|
|
242
|
+
text="首页"
|
|
243
|
+
route="/pages/index/index"
|
|
244
|
+
></hy-tabbar-item>
|
|
245
|
+
<hy-tabbar-item
|
|
246
|
+
index="1"
|
|
247
|
+
icon="mine"
|
|
248
|
+
text="我的"
|
|
249
|
+
route="/pages/mine/index"
|
|
250
|
+
></hy-tabbar-item>
|
|
251
|
+
</hy-tabbar-group>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 指示器模式
|
|
255
|
+
|
|
256
|
+
```vue
|
|
257
|
+
<hy-tabbar-group
|
|
258
|
+
v-model="current"
|
|
259
|
+
indicator-mode="bottom"
|
|
260
|
+
indicator-color="#1677ff"
|
|
261
|
+
indicator-height="3px"
|
|
262
|
+
>
|
|
263
|
+
<hy-tabbar-item index="0" icon="home" text="首页"></hy-tabbar-item>
|
|
264
|
+
<hy-tabbar-item index="1" icon="discover" text="发现"></hy-tabbar-item>
|
|
265
|
+
</hy-tabbar-group>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## 多端兼容性说明
|
|
269
|
+
|
|
270
|
+
### H5 端
|
|
271
|
+
- 支持 `vue-router` 路由跳转
|
|
272
|
+
- 支持完整的触摸反馈和波纹效果
|
|
273
|
+
- 支持所有 CSS 动画和过渡效果
|
|
274
|
+
|
|
275
|
+
### 小程序端
|
|
276
|
+
- 使用 `uni.navigateTo` 进行路由跳转
|
|
277
|
+
- 优化了触摸事件处理,确保流畅的交互体验
|
|
278
|
+
- 适配小程序的样式和布局特性
|
|
279
|
+
|
|
280
|
+
### APP 端
|
|
281
|
+
- 支持原生的触摸事件
|
|
282
|
+
- 优化了性能,减少不必要的渲染
|
|
283
|
+
- 适配不同设备的屏幕尺寸和安全区域
|
|
284
|
+
|
|
285
|
+
## 常见问题
|
|
286
|
+
|
|
287
|
+
### 1. 如何实现标签项的动态增减?
|
|
288
|
+
|
|
289
|
+
通过 `v-if` 或 `v-for` 动态渲染 `hy-tabbar-item` 组件,组件会自动注册和注销。
|
|
290
|
+
|
|
291
|
+
### 2. 如何自定义图标?
|
|
292
|
+
|
|
293
|
+
可以使用 `icon` slot 来自定义图标内容,例如:
|
|
294
|
+
|
|
295
|
+
```vue
|
|
296
|
+
<hy-tabbar-item index="0" text="首页">
|
|
297
|
+
<template #icon>
|
|
298
|
+
<image src="/static/custom-icon.png" style="width: 24px; height: 24px;"></image>
|
|
299
|
+
</template>
|
|
300
|
+
</hy-tabbar-item>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### 3. 如何处理路由跳转?
|
|
304
|
+
|
|
305
|
+
设置 `route` 属性,组件会根据不同端自动选择合适的跳转方式。
|
|
306
|
+
|
|
307
|
+
### 4. 如何适配 iPhone 的底部安全区域?
|
|
308
|
+
|
|
309
|
+
设置 `safe-area-inset-bottom` 属性为 `true`。
|
|
310
|
+
|
|
311
|
+
### 5. 如何自定义徽章样式?
|
|
312
|
+
|
|
313
|
+
使用 `badge-*` 系列属性可以自定义徽章的各种样式,如颜色、大小、位置等。
|
|
314
|
+
|
|
315
|
+
## 组件源码
|
|
316
|
+
|
|
317
|
+
- [hy-tabbar-group](https://github.com/example/hy-design-uni/blob/main/src/package/components/hy-tabbar-group)
|
|
318
|
+
- [hy-tabbar-item](https://github.com/example/hy-design-uni/blob/main/src/package/components/hy-tabbar-item)
|
|
319
|
+
|
|
320
|
+
## 更新日志
|
|
321
|
+
|
|
322
|
+
### v1.0.0
|
|
323
|
+
- 初始版本发布
|
|
324
|
+
- 支持基础的 tabbar 功能
|
|
325
|
+
- 支持自定义样式和交互效果
|
|
326
|
+
- 支持多端适配
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view
|
|
3
|
+
:class="{
|
|
4
|
+
'hy-tabbar-group__placeholder':
|
|
5
|
+
fixed && placeholder && safeAreaInsetBottom && shape === 'round'
|
|
6
|
+
}"
|
|
7
|
+
>
|
|
8
|
+
<view :class="rootClass" :style="rootStyle">
|
|
9
|
+
<slot></slot>
|
|
10
|
+
</view>
|
|
11
|
+
</view>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
export default {
|
|
16
|
+
name: 'hy-tabbar-group',
|
|
17
|
+
options: {
|
|
18
|
+
addGlobalClass: true,
|
|
19
|
+
virtualHost: true,
|
|
20
|
+
styleIsolation: 'shared'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts" setup>
|
|
26
|
+
import { computed, provide, toRefs, type CSSProperties, ref, onUnmounted } from 'vue'
|
|
27
|
+
import tabbarGroupProps from './props'
|
|
28
|
+
import type { ITabBarGroupEmits } from './typing'
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 底部导航栏,用于在不同页面之间进行切换。
|
|
32
|
+
* @displayName hy-tabbar-group
|
|
33
|
+
*/
|
|
34
|
+
defineOptions({})
|
|
35
|
+
|
|
36
|
+
const props = defineProps(tabbarGroupProps)
|
|
37
|
+
const emit = defineEmits<ITabBarGroupEmits>()
|
|
38
|
+
|
|
39
|
+
const index = ref(0) // 递增用
|
|
40
|
+
const getIndex = () => {
|
|
41
|
+
return index.value++
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
provide('hy-tabbar', {
|
|
45
|
+
...toRefs(props),
|
|
46
|
+
setChange,
|
|
47
|
+
getIndex
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// 父属性值
|
|
51
|
+
const rootStyle = computed(() => {
|
|
52
|
+
const style: CSSProperties = {
|
|
53
|
+
background: props.bgColor,
|
|
54
|
+
zIndex: props.zIndex
|
|
55
|
+
}
|
|
56
|
+
return Object.assign(style, props.customStyle)
|
|
57
|
+
})
|
|
58
|
+
// 父类名
|
|
59
|
+
const rootClass = computed(() => {
|
|
60
|
+
return [
|
|
61
|
+
'hy-tabbar-group',
|
|
62
|
+
`hy-tabbar-group--${props.shape}`,
|
|
63
|
+
props.customClass,
|
|
64
|
+
props.fixed && 'is-fixed',
|
|
65
|
+
props.safeAreaInsetBottom && 'is-safe',
|
|
66
|
+
props.border && 'is-border'
|
|
67
|
+
]
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
onUnmounted(() => {
|
|
71
|
+
index.value = 0
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 子项状态变更
|
|
76
|
+
* @param index 子项
|
|
77
|
+
*/
|
|
78
|
+
function setChange(index: string | number) {
|
|
79
|
+
emit('update:modelValue', index)
|
|
80
|
+
emit('change', {
|
|
81
|
+
value: index
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
</script>
|
|
85
|
+
<style lang="scss" scoped>
|
|
86
|
+
@import './index.scss';
|
|
87
|
+
</style>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@use "../../libs/css/theme" as *;
|
|
2
|
+
@use "../../libs/css/mixin.scss" as *;
|
|
3
|
+
|
|
4
|
+
@include b(tabbar-group) {
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
flex-wrap: nowrap;
|
|
8
|
+
position: relative;
|
|
9
|
+
background: $hy-background--container;
|
|
10
|
+
height: 100rpx;
|
|
11
|
+
|
|
12
|
+
@include e(placeholder) {
|
|
13
|
+
box-sizing: content-box;
|
|
14
|
+
padding-bottom: constant(safe-area-inset-bottom);
|
|
15
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
16
|
+
height: 100rpx;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@include m(circle) {
|
|
20
|
+
margin-left: $hy-border-margin-padding-lg;
|
|
21
|
+
margin-right: $hy-border-margin-padding-lg;
|
|
22
|
+
border-radius: $hy-border-radius-semicircle;
|
|
23
|
+
box-shadow: $hy-box-shadow;
|
|
24
|
+
|
|
25
|
+
@include is(fixed) {
|
|
26
|
+
@include is(safe) {
|
|
27
|
+
bottom: constant(safe-area-inset-bottom);
|
|
28
|
+
bottom: env(safe-area-inset-bottom);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@include m(square) {
|
|
35
|
+
|
|
36
|
+
@include is(fixed) {
|
|
37
|
+
@include is(safe) {
|
|
38
|
+
box-sizing: content-box;
|
|
39
|
+
padding-bottom: constant(safe-area-inset-bottom);
|
|
40
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@include is(border) {
|
|
46
|
+
border-top: $hy-border-line;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@include is(fixed) {
|
|
51
|
+
position: fixed;
|
|
52
|
+
left: 0;
|
|
53
|
+
bottom: 0;
|
|
54
|
+
right: 0;
|
|
55
|
+
z-index: 500;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { CSSProperties, PropType } from 'vue'
|
|
2
|
+
import type HyBadgeProps from '../hy-badge/typing'
|
|
3
|
+
|
|
4
|
+
const tabbarGroupProps = {
|
|
5
|
+
/** 选中项的索引值 */
|
|
6
|
+
modelValue: {
|
|
7
|
+
type: Number,
|
|
8
|
+
default: 0
|
|
9
|
+
},
|
|
10
|
+
/** 是否固定在底部 */
|
|
11
|
+
fixed: {
|
|
12
|
+
type: Boolean,
|
|
13
|
+
default: false
|
|
14
|
+
},
|
|
15
|
+
/** 是否显示顶部边框 */
|
|
16
|
+
border: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: true
|
|
19
|
+
},
|
|
20
|
+
/** 是否显示占位元素 */
|
|
21
|
+
placeholder: {
|
|
22
|
+
type: Boolean,
|
|
23
|
+
default: true
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* 导航栏的形状
|
|
27
|
+
* @values square, circle
|
|
28
|
+
* */
|
|
29
|
+
shape: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: 'square'
|
|
32
|
+
},
|
|
33
|
+
/** 背景颜色 */
|
|
34
|
+
bgColor: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: ''
|
|
37
|
+
},
|
|
38
|
+
/** 激活颜色 */
|
|
39
|
+
activeColor: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: ''
|
|
42
|
+
},
|
|
43
|
+
/** 非激活颜色 */
|
|
44
|
+
inactiveColor: {
|
|
45
|
+
type: String,
|
|
46
|
+
default: ''
|
|
47
|
+
},
|
|
48
|
+
/** 底部安全区域适配 - 主要用于iPhone X及以上机型 */
|
|
49
|
+
safeAreaInsetBottom: {
|
|
50
|
+
type: Boolean,
|
|
51
|
+
default: true
|
|
52
|
+
},
|
|
53
|
+
/** 图标大小 */
|
|
54
|
+
iconSize: {
|
|
55
|
+
type: [String, Number],
|
|
56
|
+
default: ''
|
|
57
|
+
},
|
|
58
|
+
/** 文字大小 */
|
|
59
|
+
fontSize: {
|
|
60
|
+
type: [String, Number],
|
|
61
|
+
default: ''
|
|
62
|
+
},
|
|
63
|
+
/** 徽标部分属性 */
|
|
64
|
+
badgeProps: {
|
|
65
|
+
type: Object as PropType<HyBadgeProps>
|
|
66
|
+
},
|
|
67
|
+
/** z-index层级 */
|
|
68
|
+
zIndex: {
|
|
69
|
+
type: Number,
|
|
70
|
+
default: 10086
|
|
71
|
+
},
|
|
72
|
+
/** 定义需要用到的外部样式 */
|
|
73
|
+
customStyle: Object as PropType<CSSProperties>,
|
|
74
|
+
/** 自定义外部类名 */
|
|
75
|
+
customClass: String
|
|
76
|
+
} as const
|
|
77
|
+
|
|
78
|
+
export default tabbarGroupProps
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ExtractPropTypes, ToRefs } from 'vue'
|
|
2
|
+
import type tabbarGroupProps from './props'
|
|
3
|
+
|
|
4
|
+
export type TabBarGroupProps = ToRefs<ExtractPropTypes<typeof tabbarGroupProps>>
|
|
5
|
+
|
|
6
|
+
export type ParamType = {
|
|
7
|
+
value: string | number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// ITabBarGroupEmits 接口定义组件的自定义事件
|
|
11
|
+
export interface ITabBarGroupEmits {
|
|
12
|
+
/** 更新选中索引 */
|
|
13
|
+
(e: 'update:modelValue', value: string | number): void
|
|
14
|
+
/** 变化事件 */
|
|
15
|
+
(e: 'change', param: ParamType): void
|
|
16
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="hy-tabbar-item" @click="handleClick">
|
|
3
|
+
<view class="hy-tabbar-item__body">
|
|
4
|
+
<hy-badge
|
|
5
|
+
:value="value"
|
|
6
|
+
:show="!!value"
|
|
7
|
+
absolute
|
|
8
|
+
:offset="tabbarConfig?.badgeProps.value?.offset || [-10, 18]"
|
|
9
|
+
:isDot="tabbarConfig?.badgeProps.value?.isDot"
|
|
10
|
+
:max="tabbarConfig?.badgeProps.value?.max"
|
|
11
|
+
:type="tabbarConfig?.badgeProps.value?.type"
|
|
12
|
+
:bgColor="tabbarConfig?.badgeProps.value?.bgColor"
|
|
13
|
+
:color="tabbarConfig?.badgeProps.value?.color"
|
|
14
|
+
:shape="tabbarConfig?.badgeProps.value?.shape"
|
|
15
|
+
:numberType="tabbarConfig?.badgeProps.value?.numberType"
|
|
16
|
+
:inverted="tabbarConfig?.badgeProps.value?.inverted"
|
|
17
|
+
>
|
|
18
|
+
</hy-badge>
|
|
19
|
+
<slot v-if="$slots.icon" name="icon" :active="active"></slot>
|
|
20
|
+
<hy-icon
|
|
21
|
+
v-else
|
|
22
|
+
:name="icon"
|
|
23
|
+
:color="iconColor"
|
|
24
|
+
:size="tabbarConfig?.iconSize?.value"
|
|
25
|
+
:custom-class="`hy-tabbar-item__body-icon ${active ? 'is-active' : 'is-inactive'}`"
|
|
26
|
+
></hy-icon>
|
|
27
|
+
<text
|
|
28
|
+
v-if="title"
|
|
29
|
+
:style="{ color: iconColor, fontSize: tabbarConfig?.fontSize?.value }"
|
|
30
|
+
:class="`hy-tabbar-item__body-title ${active ? 'is-active' : 'is-inactive'}`"
|
|
31
|
+
>
|
|
32
|
+
{{ title }}
|
|
33
|
+
</text>
|
|
34
|
+
</view>
|
|
35
|
+
</view>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script lang="ts">
|
|
39
|
+
export default {
|
|
40
|
+
name: 'hy-tabbar-item',
|
|
41
|
+
options: {
|
|
42
|
+
addGlobalClass: true,
|
|
43
|
+
virtualHost: true,
|
|
44
|
+
styleIsolation: 'shared'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<script lang="ts" setup>
|
|
50
|
+
import { computed, inject, ref } from 'vue'
|
|
51
|
+
import tabbarItemProps from './props'
|
|
52
|
+
import type { ITabbarConfig } from './typing'
|
|
53
|
+
|
|
54
|
+
// 组件
|
|
55
|
+
import HyBadge from '../hy-badge/hy-badge.vue'
|
|
56
|
+
import HyIcon from '../hy-icon/hy-icon.vue'
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 底部导航栏,用于在不同页面之间进行切换。
|
|
60
|
+
* @displayName hy-tabbar-item
|
|
61
|
+
*/
|
|
62
|
+
defineOptions({})
|
|
63
|
+
|
|
64
|
+
const props = defineProps(tabbarItemProps)
|
|
65
|
+
|
|
66
|
+
// 尝试从父组件注入配置
|
|
67
|
+
const tabbarConfig = inject<ITabbarConfig>('hy-tabbar')
|
|
68
|
+
// 获取唯一 ID
|
|
69
|
+
const uid = ref<number>(tabbarConfig?.getIndex()!)
|
|
70
|
+
|
|
71
|
+
const iconColor = computed(() => {
|
|
72
|
+
if (tabbarConfig) {
|
|
73
|
+
if (active.value && tabbarConfig.activeColor?.value) {
|
|
74
|
+
return tabbarConfig.activeColor.value
|
|
75
|
+
}
|
|
76
|
+
if (!active.value && tabbarConfig.inactiveColor?.value) {
|
|
77
|
+
return tabbarConfig.inactiveColor.value
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const active = computed(() => {
|
|
83
|
+
const name = props.name || uid.value
|
|
84
|
+
if (tabbarConfig) {
|
|
85
|
+
return tabbarConfig.modelValue.value === name
|
|
86
|
+
} else {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 点击tabbar选项
|
|
93
|
+
*/
|
|
94
|
+
function handleClick() {
|
|
95
|
+
const index: string | number = props.name || uid.value
|
|
96
|
+
if (tabbarConfig && index !== tabbarConfig?.modelValue?.value) {
|
|
97
|
+
tabbarConfig.setChange(index)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
</script>
|
|
101
|
+
<style lang="scss" scoped>
|
|
102
|
+
@import './index.scss';
|
|
103
|
+
</style>
|