hy-app 0.1.1

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 (206) hide show
  1. package/README.md +42 -0
  2. package/api/http.ts +138 -0
  3. package/api/index.ts +1 -0
  4. package/common/index.ts +1 -0
  5. package/common/versionControl.ts +102 -0
  6. package/components/dialog/TheDialog.vue +128 -0
  7. package/components/dialog/index.ts +38 -0
  8. package/components/hy-address-picker/hy-address-picker.vue +262 -0
  9. package/components/hy-address-picker/props.ts +27 -0
  10. package/components/hy-address-picker/typing.d.ts +98 -0
  11. package/components/hy-avatar/hy-avatar.vue +217 -0
  12. package/components/hy-avatar/props.ts +20 -0
  13. package/components/hy-avatar/typing.d.ts +64 -0
  14. package/components/hy-back-top/hy-back-top.vue +71 -0
  15. package/components/hy-back-top/props.ts +23 -0
  16. package/components/hy-back-top/typing.d.ts +49 -0
  17. package/components/hy-badge/hy-badge.vue +155 -0
  18. package/components/hy-badge/props.ts +19 -0
  19. package/components/hy-badge/typing.d.ts +60 -0
  20. package/components/hy-button/hy-button.vue +394 -0
  21. package/components/hy-button/props.ts +36 -0
  22. package/components/hy-button/typing.d.ts +125 -0
  23. package/components/hy-card/hy-card.vue +198 -0
  24. package/components/hy-card/props.ts +29 -0
  25. package/components/hy-card/typing.d.ts +112 -0
  26. package/components/hy-cell/hy-cell.vue +268 -0
  27. package/components/hy-cell/props.ts +20 -0
  28. package/components/hy-cell/typing.d.ts +98 -0
  29. package/components/hy-check-button/hy-check-button.vue +71 -0
  30. package/components/hy-check-button/props.ts +20 -0
  31. package/components/hy-check-button/typing.d.ts +79 -0
  32. package/components/hy-checkbox/hy-checkbox.vue +299 -0
  33. package/components/hy-checkbox/props.ts +28 -0
  34. package/components/hy-checkbox/typing.d.ts +77 -0
  35. package/components/hy-datetime-picker/hy-datetime-picker.vue +584 -0
  36. package/components/hy-datetime-picker/props.ts +36 -0
  37. package/components/hy-datetime-picker/typing.d.ts +135 -0
  38. package/components/hy-divider/hy-divider.vue +164 -0
  39. package/components/hy-divider/props.ts +21 -0
  40. package/components/hy-divider/typing.d.ts +64 -0
  41. package/components/hy-empty/hy-empty.vue +122 -0
  42. package/components/hy-empty/props.ts +21 -0
  43. package/components/hy-empty/typing.d.ts +68 -0
  44. package/components/hy-folding-panel/hy-folding-panel.vue +94 -0
  45. package/components/hy-folding-panel/props.ts +17 -0
  46. package/components/hy-folding-panel/typing.d.ts +59 -0
  47. package/components/hy-form/hy-form.vue +372 -0
  48. package/components/hy-form/props.ts +15 -0
  49. package/components/hy-form/typing.d.ts +51 -0
  50. package/components/hy-grid/hy-grid.vue +126 -0
  51. package/components/hy-grid/props.ts +16 -0
  52. package/components/hy-grid/typing.d.ts +62 -0
  53. package/components/hy-icon/hy-icon.vue +207 -0
  54. package/components/hy-icon/props.ts +24 -0
  55. package/components/hy-icon/typing.d.ts +80 -0
  56. package/components/hy-input/hy-input.vue +402 -0
  57. package/components/hy-input/props.ts +41 -0
  58. package/components/hy-input/typing.d.ts +148 -0
  59. package/components/hy-line/hy-line.vue +44 -0
  60. package/components/hy-line/props.ts +12 -0
  61. package/components/hy-line/typing.d.ts +32 -0
  62. package/components/hy-line-progress/hy-line-progress.vue +118 -0
  63. package/components/hy-line-progress/props.ts +12 -0
  64. package/components/hy-line-progress/typing.d.ts +28 -0
  65. package/components/hy-list/hy-list.vue +250 -0
  66. package/components/hy-list/props.ts +18 -0
  67. package/components/hy-list/typing.d.ts +50 -0
  68. package/components/hy-login/ThePhoneLogin.vue +106 -0
  69. package/components/hy-login/TheUserLogin.vue +391 -0
  70. package/components/hy-login/hy-login.vue +283 -0
  71. package/components/hy-login/props.ts +32 -0
  72. package/components/hy-login/typing.d.ts +60 -0
  73. package/components/hy-modal/hy-modal.vue +240 -0
  74. package/components/hy-modal/props.ts +24 -0
  75. package/components/hy-modal/typing.d.ts +70 -0
  76. package/components/hy-navbar/hy-navbar.vue +194 -0
  77. package/components/hy-navbar/props.ts +24 -0
  78. package/components/hy-navbar/typing.d.ts +81 -0
  79. package/components/hy-notice-bar/hy-column-notice.vue +130 -0
  80. package/components/hy-notice-bar/hy-notice-bar.vue +82 -0
  81. package/components/hy-notice-bar/hy-row-notice.vue +182 -0
  82. package/components/hy-notice-bar/props.ts +19 -0
  83. package/components/hy-notice-bar/typing.d.ts +56 -0
  84. package/components/hy-number-step/hy-number-step.vue +428 -0
  85. package/components/hy-number-step/props.ts +29 -0
  86. package/components/hy-number-step/typing.d.ts +104 -0
  87. package/components/hy-overlay/hy-overlay.vue +54 -0
  88. package/components/hy-overlay/props.ts +10 -0
  89. package/components/hy-overlay/typing.d.ts +24 -0
  90. package/components/hy-picker/hy-picker.vue +499 -0
  91. package/components/hy-picker/props.ts +30 -0
  92. package/components/hy-picker/typing.d.ts +115 -0
  93. package/components/hy-popup/hy-popup.vue +269 -0
  94. package/components/hy-popup/props.ts +21 -0
  95. package/components/hy-popup/typing.d.ts +68 -0
  96. package/components/hy-price/hy-price.vue +86 -0
  97. package/components/hy-price/props.ts +13 -0
  98. package/components/hy-price/typing.d.ts +36 -0
  99. package/components/hy-qrcode/hy-qrcode.vue +153 -0
  100. package/components/hy-qrcode/props.ts +20 -0
  101. package/components/hy-qrcode/qrcode.js +1364 -0
  102. package/components/hy-qrcode/typing.d.ts +64 -0
  103. package/components/hy-radio/hy-radio.vue +319 -0
  104. package/components/hy-radio/props.ts +28 -0
  105. package/components/hy-radio/typing.d.ts +85 -0
  106. package/components/hy-rate/hy-rate.vue +261 -0
  107. package/components/hy-rate/props.ts +18 -0
  108. package/components/hy-rate/typing.d.ts +60 -0
  109. package/components/hy-read-more/hy-read-more.vue +134 -0
  110. package/components/hy-read-more/props.ts +20 -0
  111. package/components/hy-read-more/typing.d.ts +44 -0
  112. package/components/hy-safe-bottom/hy-safe-bottom.vue +64 -0
  113. package/components/hy-scroll-list/hy-scroll-list.vue +146 -0
  114. package/components/hy-scroll-list/props.ts +12 -0
  115. package/components/hy-scroll-list/typing.d.ts +28 -0
  116. package/components/hy-search/hy-search.vue +294 -0
  117. package/components/hy-search/props.ts +29 -0
  118. package/components/hy-search/typing.d.ts +109 -0
  119. package/components/hy-slider/hy-slider.vue +511 -0
  120. package/components/hy-slider/props.ts +21 -0
  121. package/components/hy-slider/typing.d.ts +68 -0
  122. package/components/hy-steps/hy-steps.vue +352 -0
  123. package/components/hy-steps/props.ts +15 -0
  124. package/components/hy-steps/typing.d.ts +58 -0
  125. package/components/hy-subsection/hy-subsection.vue +272 -0
  126. package/components/hy-subsection/props.ts +16 -0
  127. package/components/hy-subsection/typing.d.ts +44 -0
  128. package/components/hy-swiper/hy-swiper-indicator.vue +105 -0
  129. package/components/hy-swiper/hy-swiper.vue +242 -0
  130. package/components/hy-swiper/props.ts +30 -0
  131. package/components/hy-swiper/typing.d.ts +107 -0
  132. package/components/hy-switch/hy-switch.vue +168 -0
  133. package/components/hy-switch/props.ts +16 -0
  134. package/components/hy-switch/typing.d.ts +48 -0
  135. package/components/hy-tabs/hy-tabs.vue +416 -0
  136. package/components/hy-tabs/props.ts +26 -0
  137. package/components/hy-tabs/typing.d.ts +86 -0
  138. package/components/hy-tag/hy-tag.vue +374 -0
  139. package/components/hy-tag/props.ts +22 -0
  140. package/components/hy-tag/typing.d.ts +76 -0
  141. package/components/hy-textarea/hy-textarea.vue +229 -0
  142. package/components/hy-textarea/props.ts +26 -0
  143. package/components/hy-textarea/typing.d.ts +27 -0
  144. package/components/hy-tooltip/hy-tooltip.vue +332 -0
  145. package/components/hy-tooltip/props.ts +17 -0
  146. package/components/hy-tooltip/typing.d.ts +52 -0
  147. package/components/hy-transition/hy-transition.vue +150 -0
  148. package/components/hy-transition/index.scss +113 -0
  149. package/components/hy-transition/props.ts +10 -0
  150. package/components/hy-transition/typing.d.ts +36 -0
  151. package/components/hy-upload/hy-upload.vue +557 -0
  152. package/components/hy-upload/props.ts +29 -0
  153. package/components/hy-upload/typing.d.ts +147 -0
  154. package/components/hy-warn/hy-warn.vue +228 -0
  155. package/components/hy-warn/props.ts +14 -0
  156. package/components/hy-warn/typing.d.ts +40 -0
  157. package/components/hy-waterfall/hy-waterfall.vue +51 -0
  158. package/components/hy-waterfall/props.ts +10 -0
  159. package/components/hy-waterfall/typing.d.ts +20 -0
  160. package/components/index.ts +162 -0
  161. package/components/message/TheMessage.vue +169 -0
  162. package/components/message/index.ts +54 -0
  163. package/components/u-form/form.js +22 -0
  164. package/components/u-form/hy-form.vue +324 -0
  165. package/components/u-form/props.js +49 -0
  166. package/components/u-form/schema.js +1451 -0
  167. package/components/u-form/u-form.vue +267 -0
  168. package/components/u-form/utils.js +65 -0
  169. package/components/u-form-item/formItem.js +24 -0
  170. package/components/u-form-item/hy-form-item.vue +360 -0
  171. package/components/u-form-item/props.js +57 -0
  172. package/components/u-form-item/u-form-item.vue +294 -0
  173. package/components/yk-dialog/yk-dialog.vue +129 -0
  174. package/components/yk-tabbar/props.ts +49 -0
  175. package/components/yk-tabbar/yk-tabbar.vue +224 -0
  176. package/config/color.ts +6 -0
  177. package/config/icon.ts +366 -0
  178. package/config/index.ts +2 -0
  179. package/global/index.ts +6 -0
  180. package/global/register-properties.ts +37 -0
  181. package/index.ts +8 -0
  182. package/libs/css/common.scss +0 -0
  183. package/libs/css/iconfont.css +379 -0
  184. package/libs/css/iconfont.ttf +0 -0
  185. package/libs/css/mixin.scss +15 -0
  186. package/package.json +42 -0
  187. package/public/icons/error.png +0 -0
  188. package/public/icons/success.png +0 -0
  189. package/public/icons/warning.png +0 -0
  190. package/store/index.ts +1 -0
  191. package/store/userInfo.ts +25 -0
  192. package/theme.scss +94 -0
  193. package/typing/index.ts +7 -0
  194. package/typing/modules/common.d.ts +50 -0
  195. package/typing/modules/dialog.ts +17 -0
  196. package/typing/modules/enum.ts +67 -0
  197. package/typing/modules/form.ts +161 -0
  198. package/typing/modules/http.ts +68 -0
  199. package/typing/modules/icon.d.ts +366 -0
  200. package/typing/modules/img.ts +15 -0
  201. package/typing/modules/rect.ts +10 -0
  202. package/utils/address.json +5890 -0
  203. package/utils/base64.ts +119 -0
  204. package/utils/index.ts +3 -0
  205. package/utils/inside.ts +310 -0
  206. package/utils/utils.ts +446 -0
@@ -0,0 +1,16 @@
1
+ import IProps from "./typing";
2
+ import { ColorConfig } from "../../config";
3
+
4
+ const defaultProps: IProps = {
5
+ modelValue: false,
6
+ loading: false,
7
+ disabled: false,
8
+ size: 25,
9
+ activeColor: ColorConfig.primary,
10
+ inactiveColor: "#ffffff",
11
+ activeValue: true,
12
+ inactiveValue: false,
13
+ asyncChange: false,
14
+ space: 0
15
+ };
16
+ export default defaultProps;
@@ -0,0 +1,48 @@
1
+ import type { CSSProperties } from "vue";
2
+
3
+ export default interface IProps {
4
+ /**
5
+ * @description 通过v-model双向绑定的值 (默认 false )
6
+ * */
7
+ modelValue: boolean;
8
+ /**
9
+ * @description 是否处于加载中(默认 false )
10
+ * */
11
+ loading?: boolean;
12
+ /**
13
+ * @description 是否禁用(默认 false )
14
+ * */
15
+ disabled?: boolean;
16
+ /**
17
+ * @description 开关尺寸,单位px (默认 25 )
18
+ * */
19
+ size?: number;
20
+ /**
21
+ * @description 打开时的背景色 (默认 '#2979ff' )
22
+ * */
23
+ activeColor?: string;
24
+ /**
25
+ * @description 关闭时的背景色 (默认 '#ffffff' )
26
+ * */
27
+ inactiveColor?: string;
28
+ /**
29
+ * @description 打开选择器时通过change事件发出的值 (默认 true )
30
+ * */
31
+ activeValue?: boolean;
32
+ /**
33
+ * @description 关闭选择器时通过change事件发出的值 (默认 false )
34
+ * */
35
+ inactiveValue?: boolean;
36
+ /**
37
+ * @description 是否开启异步变更,开启后需要手动控制输入值 (默认 false )
38
+ * */
39
+ asyncChange?: boolean;
40
+ /**
41
+ * @description 圆点与外边框的距离 (默认 0 )
42
+ * */
43
+ space?: number;
44
+ /**
45
+ * @description 定义需要用到的外部样式
46
+ * */
47
+ customStyle?: CSSProperties;
48
+ }
@@ -0,0 +1,416 @@
1
+ <template>
2
+ <view class="hy-tabs">
3
+ <view class="hy-tabs__wrapper">
4
+ <slot name="left" />
5
+ <view class="hy-tabs__wrapper__scroll-view-wrapper">
6
+ <scroll-view
7
+ :scroll-x="scrollable"
8
+ :scroll-left="scrollLeft"
9
+ scroll-with-animation
10
+ class="hy-tabs__wrapper__scroll-view"
11
+ :show-scrollbar="false"
12
+ ref="hy-tabs__wrapper__scroll-view"
13
+ >
14
+ <view class="hy-tabs__wrapper__nav" ref="hy-tabs__wrapper__nav">
15
+ <view
16
+ v-for="(item, index) in list"
17
+ :key="index"
18
+ @tap="clickHandler(item, index)"
19
+ @longpress="longPressHandler(item, index)"
20
+ :ref="`u-tabs__wrapper__nav__item-${index}`"
21
+ :style="[itemStyle, { flex: scrollable ? '' : 1 }]"
22
+ :class="[
23
+ 'hy-tabs__wrapper__nav__item',
24
+ `hy-tabs__wrapper__nav__item-${index}`,
25
+ item.disabled && 'hy-tabs__wrapper__nav__item--disabled',
26
+ innerCurrent == index
27
+ ? 'hy-tabs__wrapper__nav__item-active'
28
+ : ''
29
+ ]"
30
+ >
31
+ <slot
32
+ v-if="$slots.icon"
33
+ name="icon"
34
+ :record="item"
35
+ :index="index"
36
+ />
37
+ <template v-else>
38
+ <view
39
+ class="hy-tabs__wrapper__nav__item__prefix-icon"
40
+ v-if="item.icon"
41
+ >
42
+ <HyIcon :name="item.icon" :customStyle="iconStyle"></HyIcon>
43
+ </view>
44
+ </template>
45
+ <slot
46
+ v-if="$slots.content"
47
+ name="content"
48
+ :record="item"
49
+ :index="index"
50
+ />
51
+ <text
52
+ v-else
53
+ :class="[
54
+ item.disabled && 'hy-tabs__wrapper__nav__item__text--disabled'
55
+ ]"
56
+ class="hy-tabs__wrapper__nav__item__text"
57
+ :style="[textStyle(index)]"
58
+ >{{ item[keyName] }}</text
59
+ >
60
+ <HyBadge
61
+ :show="
62
+ !!(
63
+ item?.badge &&
64
+ (item?.badge?.show ||
65
+ item?.badge?.isDot ||
66
+ item?.badge?.value)
67
+ )
68
+ "
69
+ :isDot="
70
+ (item?.badge && item?.badge?.isDot) || propsBadge?.isDot
71
+ "
72
+ :value="
73
+ (item?.badge && item?.badge?.value) || propsBadge?.value
74
+ "
75
+ :max="(item?.badge && item?.badge?.max) || propsBadge?.max"
76
+ :type="(item?.badge && item?.badge?.type) || propsBadge?.type"
77
+ :showZero="
78
+ (item?.badge && item?.badge?.showZero) || propsBadge?.showZero
79
+ "
80
+ :bgColor="
81
+ (item?.badge && item?.badge?.bgColor) || propsBadge?.bgColor
82
+ "
83
+ :color="
84
+ (item?.badge && item?.badge?.color) || propsBadge?.color
85
+ "
86
+ :shape="
87
+ (item?.badge && item?.badge?.shape) || propsBadge?.shape
88
+ "
89
+ :numberType="
90
+ (item?.badge && item?.badge?.numberType) ||
91
+ propsBadge?.numberType
92
+ "
93
+ :inverted="
94
+ (item?.badge && item?.badge?.inverted) || propsBadge?.inverted
95
+ "
96
+ :customStyle="{
97
+ marginLeft: '4px'
98
+ }"
99
+ ></HyBadge>
100
+ </view>
101
+ <!-- #ifndef APP-NVUE -->
102
+ <view
103
+ class="hy-tabs__wrapper__nav__line"
104
+ ref="hy-tabs__wrapper__nav__line"
105
+ :style="[
106
+ {
107
+ width: addUnit(lineWidth),
108
+ transform: `translate(${lineOffsetLeft}px)`,
109
+ transitionDuration: `${firstTime ? 0 : duration}ms`,
110
+ height: addUnit(lineHeight),
111
+ background: lineColor,
112
+ backgroundSize: lineBgSize
113
+ }
114
+ ]"
115
+ >
116
+ </view>
117
+ <!-- #endif -->
118
+ </view>
119
+ </scroll-view>
120
+ </view>
121
+ <slot name="right" />
122
+ </view>
123
+ </view>
124
+
125
+ <!-- 内容轮播图 -->
126
+ <slot name="main">
127
+ <swiper
128
+ :current="innerCurrent"
129
+ @animationfinish="animationFinish"
130
+ :style="{ height: swiperHeight }"
131
+ >
132
+ <swiper-item class="swiper-item" v-for="(item, i) in list" :key="i">
133
+ <slot :record="item.content" />
134
+ </swiper-item>
135
+ </swiper>
136
+ </slot>
137
+ </template>
138
+
139
+ <script setup lang="ts">
140
+ import {
141
+ computed,
142
+ CSSProperties,
143
+ toRefs,
144
+ ref,
145
+ watch,
146
+ nextTick,
147
+ onMounted
148
+ } from "vue";
149
+ import defaultProps from "./props";
150
+ import IProps, { TabsItemVo } from "./typing";
151
+ import { addUnit, getPx, getRect, sleep } from "../../utils";
152
+
153
+ // 组件
154
+ import HyBadge from "../hy-badge/hy-badge.vue";
155
+ import HyIcon from "../hy-icon/hy-icon.vue";
156
+
157
+ const props = withDefaults(defineProps<IProps>(), defaultProps);
158
+ const { list, current, activeStyle, lineWidth, inactiveStyle } = toRefs(props);
159
+ const emit = defineEmits(["click", "longPress", "update:current", "change"]);
160
+
161
+ const firstTime = ref<boolean>(true);
162
+ const scrollLeft = ref<number>(0);
163
+ const scrollViewWidth = ref<number>(0);
164
+ const lineOffsetLeft = ref<number>(0);
165
+ const tabsRect = ref<UniApp.NodeInfo>({
166
+ left: 0
167
+ });
168
+ const innerCurrent = ref<number>(0);
169
+
170
+ watch(
171
+ () => current.value,
172
+ (newValue: number) => {
173
+ // 内外部值不相等时,才尝试移动滑块
174
+ if (newValue !== innerCurrent.value) {
175
+ innerCurrent.value = newValue;
176
+ nextTick(() => {
177
+ resize();
178
+ });
179
+ }
180
+ },
181
+ { immediate: true }
182
+ );
183
+ watch(
184
+ () => list.value,
185
+ () => resize()
186
+ );
187
+
188
+ const textStyle = computed(() => {
189
+ return (index: number): CSSProperties => {
190
+ const style: CSSProperties = {};
191
+ // 取当期是否激活的样式
192
+ const customStyle =
193
+ index == innerCurrent.value ? activeStyle.value : inactiveStyle.value;
194
+ // 如果当前菜单被禁用,则加上对应颜色,需要在此做处理,是因为nvue下,无法在style样式中通过!import覆盖标签的内联样式
195
+ if (list.value[index]?.disabled) {
196
+ style.color = "#c8c9cc";
197
+ }
198
+ return Object.assign(customStyle, style);
199
+ };
200
+ });
201
+
202
+ onMounted(() => {
203
+ resize();
204
+ });
205
+
206
+ /**
207
+ * @description 设置线左边距离
208
+ */
209
+ const setLineLeft = () => {
210
+ const tabItem = list.value[innerCurrent.value];
211
+ if (!tabItem) {
212
+ return;
213
+ }
214
+ // 获取滑块该移动的位置
215
+ let lineOffsetLeft_1 = list.value
216
+ .slice(0, innerCurrent.value)
217
+ .reduce((total, curr) => total + curr.rect.width, 0);
218
+ // 获取下划线的数值px表示法
219
+ lineOffsetLeft.value =
220
+ lineOffsetLeft_1 + (tabItem.rect.width - getPx(lineWidth.value)) / 2;
221
+
222
+ // 如果是第一次执行此方法,让滑块在初始化时,瞬间滑动到第一个tab item的中间
223
+ // 这里需要一个定时器,因为在非nvue下,是直接通过style绑定过渡时间,需要等其过渡完成后,再设置为false(非第一次移动滑块)
224
+ if (firstTime.value) {
225
+ sleep().then(() => {
226
+ firstTime.value = false;
227
+ });
228
+ }
229
+ };
230
+ // 点击某一个标签
231
+ const clickHandler = (item: TabsItemVo, index: number) => {
232
+ // 因为标签可能为disabled状态,所以click是一定会发出的,但是change事件是需要可用的状态才发出
233
+ emit(
234
+ "click",
235
+ {
236
+ ...item,
237
+ index
238
+ },
239
+ index
240
+ );
241
+ // 如果disabled状态,返回
242
+ if (item.disabled) return;
243
+ innerCurrent.value = index;
244
+ resize();
245
+ emit("update:current", index);
246
+ emit("change", item, index);
247
+ };
248
+ // 长按事件
249
+ const longPressHandler = (item: TabsItemVo, index: number) => {
250
+ emit("longPress", {
251
+ ...item,
252
+ index
253
+ });
254
+ };
255
+ const setScrollLeft = () => {
256
+ // 当前活动tab的布局信息,有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
257
+ if (innerCurrent.value < 0) {
258
+ innerCurrent.value = 0;
259
+ }
260
+ const tabRect = list.value[innerCurrent.value];
261
+ // 累加得到当前item到左边的距离
262
+ const offsetLeft = list.value
263
+ .slice(0, innerCurrent.value)
264
+ .reduce((total: number, curr) => {
265
+ return total + curr.rect.width;
266
+ }, 0);
267
+ // 此处为屏幕宽度
268
+ const windowWidth = uni.getWindowInfo().windowWidth;
269
+ // 将活动的tabs-item移动到屏幕正中间,实际上是对scroll-view的移动
270
+ let scrollLeft_1 =
271
+ offsetLeft -
272
+ ((tabsRect.value.width || 0) - tabRect.rect.width) / 2 -
273
+ (windowWidth - (tabsRect.value.right || 0)) / 2 +
274
+ (tabsRect.value.left || 0) / 2;
275
+ // 这里做一个限制,限制scrollLeft的最大值为整个scroll-view宽度减去tabs组件的宽度
276
+ scrollLeft_1 = Math.min(
277
+ scrollLeft_1,
278
+ scrollViewWidth.value - (tabsRect.value.width || 0)
279
+ );
280
+ scrollLeft.value = Math.max(0, scrollLeft_1);
281
+ };
282
+ /**
283
+ * @description 获取所有标签的尺寸
284
+ * */
285
+ const resize = () => {
286
+ // 如果不存在list,则不处理
287
+ if (list.value.length === 0) {
288
+ return;
289
+ }
290
+ Promise.all([getTabsRect(), getAllItemRect()]).then(
291
+ ([tabsRect_1, itemRect = []]: (UniApp.NodeInfo | any)[]) => {
292
+ // 兼容在swiper组件中使用
293
+ if (
294
+ tabsRect_1.left &&
295
+ tabsRect_1.width &&
296
+ tabsRect_1.right &&
297
+ tabsRect_1.left > tabsRect_1.width
298
+ ) {
299
+ tabsRect_1.right =
300
+ tabsRect_1.right -
301
+ Math.floor(tabsRect_1.left / tabsRect_1.width) * tabsRect_1.width;
302
+ tabsRect_1.left = tabsRect_1.left % tabsRect_1.width;
303
+ }
304
+ // console.log(tabsRect)
305
+ tabsRect.value = tabsRect_1;
306
+ scrollViewWidth.value = 0;
307
+ itemRect.map((item: UniApp.NodeInfo, index: number) => {
308
+ // 计算scroll-view的宽度,这里
309
+ scrollViewWidth.value += item.width || 0;
310
+ // 另外计算每一个item的中心点X轴坐标
311
+ list.value[index].rect = item;
312
+ });
313
+ // 获取了tabs的尺寸之后,设置滑块的位置
314
+ setLineLeft();
315
+ setScrollLeft();
316
+ }
317
+ );
318
+ };
319
+ /**
320
+ * @description 获取导航菜单的尺寸
321
+ * */
322
+ const getTabsRect = () => {
323
+ return new Promise((resolve) => {
324
+ getRect(".hy-tabs__wrapper__scroll-view").then((size) => resolve(size));
325
+ });
326
+ };
327
+ /**
328
+ * @description 获取所有标签的尺寸
329
+ * */
330
+ const getAllItemRect = () => {
331
+ return new Promise((resolve) => {
332
+ const promiseAllArr = list.value.map((item, index) =>
333
+ getRect(`.hy-tabs__wrapper__nav__item-${index}`)
334
+ );
335
+ Promise.all(promiseAllArr).then((sizes) => resolve(sizes));
336
+ });
337
+ };
338
+
339
+ /**
340
+ * 滑动页面改变当前值
341
+ * */
342
+ const animationFinish = (e: any) => {
343
+ // 轮播图选项值
344
+ innerCurrent.value = e.detail.current;
345
+ resize();
346
+ if (e.detail.source === "touch") {
347
+ emit("change", list.value[current.value], current.value);
348
+ }
349
+ };
350
+ </script>
351
+
352
+ <style lang="scss" scoped>
353
+ @import "../../libs/css/mixin.scss";
354
+ @import "../../theme.scss";
355
+
356
+ .hy-tabs {
357
+ &__wrapper {
358
+ @include flex;
359
+ align-items: center;
360
+
361
+ &__scroll-view-wrapper {
362
+ flex: 1;
363
+ /* #ifndef APP-NVUE */
364
+ overflow: auto hidden;
365
+ /* #endif */
366
+ }
367
+
368
+ &__scroll-view {
369
+ @include flex;
370
+ flex: 1;
371
+ }
372
+
373
+ &__nav {
374
+ @include flex;
375
+ position: relative;
376
+
377
+ &__item {
378
+ padding: 0 11px;
379
+ @include flex;
380
+ align-items: center;
381
+ justify-content: center;
382
+ /* #ifdef H5 */
383
+ cursor: pointer;
384
+ /* #endif */
385
+
386
+ &--disabled {
387
+ /* #ifdef H5 */
388
+ cursor: not-allowed;
389
+ /* #endif */
390
+ }
391
+
392
+ &__text {
393
+ font-size: 15px;
394
+ color: $hy-text-color-grey;
395
+ white-space: nowrap !important;
396
+
397
+ &--disabled {
398
+ color: $hy-color-disable-bg !important;
399
+ }
400
+ }
401
+ }
402
+
403
+ &__line {
404
+ height: 3px;
405
+ background: $hy-primary;
406
+ width: 30px;
407
+ position: absolute;
408
+ bottom: 2px;
409
+ border-radius: 100px;
410
+ transition-property: transform;
411
+ transition-duration: 300ms;
412
+ }
413
+ }
414
+ }
415
+ }
416
+ </style>
@@ -0,0 +1,26 @@
1
+ import IProps from "./typing";
2
+
3
+ const defaultProps: IProps = {
4
+ list: [],
5
+ current: 0,
6
+ keyName: "name",
7
+ duration: 300,
8
+ lineColor: "#3c9cff",
9
+ activeStyle: {
10
+ color: "#303133"
11
+ },
12
+ inactiveStyle: {
13
+ color: "#606266"
14
+ },
15
+ lineWidth: 20,
16
+ lineHeight: 3,
17
+ lineBgSize: "cover",
18
+ itemStyle: {
19
+ height: "44px"
20
+ },
21
+ swiperHeight: "calc(100vh - 44px)",
22
+ scrollable: true,
23
+ iconStyle: {}
24
+ };
25
+
26
+ export default defaultProps;
@@ -0,0 +1,86 @@
1
+ import { CSSProperties } from "vue";
2
+ import BadgeProps from "../hy-badge/typing";
3
+ export interface TabsItemVo extends AnyObject {
4
+ /**
5
+ * @description tab名称
6
+ * */
7
+ name: string;
8
+ /**
9
+ * @description 徽标接收的props
10
+ * */
11
+ badge?: BadgeProps;
12
+ /**
13
+ * @description 是否禁用
14
+ * */
15
+ disabled?: boolean;
16
+ /**
17
+ * @description swiper内容值
18
+ * */
19
+ content?: any;
20
+ }
21
+ export default interface IProps {
22
+ /**
23
+ * @description 标签数组,元素为对象,如[{name: '推荐'}]
24
+ * */
25
+ list: TabsItemVo[];
26
+ /**
27
+ * @description 当前选中标签的索引
28
+ * */
29
+ current?: number;
30
+ /**
31
+ * @description 从list元素对象中读取的键名
32
+ * */
33
+ keyName?: string;
34
+ /**
35
+ * @description 滑块移动一次所需的时间,单位秒(默认 200 )
36
+ * */
37
+ duration?: number;
38
+ /**
39
+ * @description 滑块颜色
40
+ * */
41
+ lineColor?: string;
42
+ /**
43
+ * @description 菜单选择中时的样式
44
+ * */
45
+ activeStyle?: CSSProperties;
46
+ /**
47
+ * @description 菜单非选中时的样式
48
+ * */
49
+ inactiveStyle?: CSSProperties;
50
+ /**
51
+ * @description 滑块长度(默认20)
52
+ * */
53
+ lineWidth?: number | string;
54
+ /**
55
+ * @description 滑块高度(默认3)
56
+ * */
57
+ lineHeight?: number | string;
58
+ /**
59
+ * @description 滑块背景显示大小,当滑块背景设置为图片时使用
60
+ * */
61
+ lineBgSize?: number | string;
62
+ /**
63
+ * @description 菜单item的样式
64
+ * */
65
+ itemStyle?: CSSProperties;
66
+ /**
67
+ * @description 菜单是否可滚动
68
+ * */
69
+ scrollable?: boolean;
70
+ /**
71
+ * @description 徽标props全局定义
72
+ * */
73
+ propsBadge?: BadgeProps;
74
+ /**
75
+ * @description 轮播图高度
76
+ * */
77
+ swiperHeight?: string | number;
78
+ /**
79
+ * @description 标签左侧图标样式自定义
80
+ * */
81
+ iconStyle?: CSSProperties;
82
+ /**
83
+ * @description 定义需要用到的外部样式
84
+ * */
85
+ customStyle?: CSSProperties;
86
+ }