uview-pro 0.6.18 → 0.6.19

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 (278) hide show
  1. package/changelog.md +1778 -1768
  2. package/components/u-action-sheet/types.ts +52 -52
  3. package/components/u-action-sheet/u-action-sheet.vue +196 -196
  4. package/components/u-action-sheet-item/types.ts +35 -35
  5. package/components/u-action-sheet-item/u-action-sheet-item.vue +85 -85
  6. package/components/u-alert-tips/types.ts +49 -49
  7. package/components/u-alert-tips/u-alert-tips.vue +239 -239
  8. package/components/u-avatar/types.ts +44 -44
  9. package/components/u-avatar/u-avatar.vue +218 -218
  10. package/components/u-avatar-cropper/types.ts +23 -23
  11. package/components/u-avatar-cropper/u-avatar-cropper.vue +299 -299
  12. package/components/u-avatar-cropper/weCropper.d.ts +62 -62
  13. package/components/u-avatar-cropper/weCropper.js +1281 -1281
  14. package/components/u-avatar-cropper/weCropper.ts +1276 -1276
  15. package/components/u-back-top/types.ts +44 -44
  16. package/components/u-back-top/u-back-top.vue +141 -141
  17. package/components/u-badge/types.ts +46 -46
  18. package/components/u-badge/u-badge.vue +153 -153
  19. package/components/u-button/types.ts +76 -76
  20. package/components/u-button/u-button.vue +608 -608
  21. package/components/u-calendar/types.ts +126 -126
  22. package/components/u-calendar/u-calendar.vue +1243 -1243
  23. package/components/u-car-keyboard/types.ts +22 -22
  24. package/components/u-car-keyboard/u-car-keyboard.vue +263 -263
  25. package/components/u-card/types.ts +69 -69
  26. package/components/u-card/u-card.vue +210 -210
  27. package/components/u-cell-group/types.ts +27 -27
  28. package/components/u-cell-group/u-cell-group.vue +60 -60
  29. package/components/u-cell-item/types.ts +64 -64
  30. package/components/u-cell-item/u-cell-item.vue +221 -221
  31. package/components/u-checkbox/types.ts +45 -45
  32. package/components/u-checkbox/u-checkbox.vue +363 -363
  33. package/components/u-checkbox-group/types.ts +45 -45
  34. package/components/u-checkbox-group/u-checkbox-group.vue +172 -172
  35. package/components/u-circle-progress/types.ts +63 -63
  36. package/components/u-circle-progress/u-circle-progress.vue +299 -299
  37. package/components/u-city-select/types.ts +30 -30
  38. package/components/u-city-select/u-city-select.vue +281 -281
  39. package/components/u-col/types.ts +40 -40
  40. package/components/u-col/u-col.vue +142 -142
  41. package/components/u-collapse/types.ts +41 -41
  42. package/components/u-collapse/u-collapse.vue +190 -190
  43. package/components/u-collapse-item/types.ts +35 -35
  44. package/components/u-collapse-item/u-collapse-item.vue +291 -291
  45. package/components/u-column-notice/types.ts +58 -58
  46. package/components/u-column-notice/u-column-notice.vue +223 -223
  47. package/components/u-config-provider/types.ts +53 -53
  48. package/components/u-config-provider/u-config-provider.vue +185 -185
  49. package/components/u-count-down/types.ts +52 -52
  50. package/components/u-count-down/u-count-down.vue +288 -288
  51. package/components/u-count-to/types.ts +42 -42
  52. package/components/u-count-to/u-count-to.vue +266 -266
  53. package/components/u-divider/types.ts +41 -41
  54. package/components/u-divider/u-divider.vue +146 -146
  55. package/components/u-dropdown/types.ts +67 -67
  56. package/components/u-dropdown/u-dropdown.vue +436 -436
  57. package/components/u-dropdown-item/types.ts +40 -40
  58. package/components/u-dropdown-item/u-dropdown-item.vue +124 -124
  59. package/components/u-empty/types.ts +46 -46
  60. package/components/u-empty/u-empty.vue +109 -109
  61. package/components/u-fab/types.ts +83 -83
  62. package/components/u-fab/u-fab.vue +330 -330
  63. package/components/u-field/types.ts +81 -81
  64. package/components/u-field/u-field.vue +398 -398
  65. package/components/u-form/types.ts +39 -39
  66. package/components/u-form/u-form.vue +175 -135
  67. package/components/u-form-item/types.ts +95 -95
  68. package/components/u-form-item/u-form-item.vue +563 -563
  69. package/components/u-full-screen/types.ts +26 -26
  70. package/components/u-full-screen/u-full-screen.vue +100 -100
  71. package/components/u-gap/types.ts +28 -28
  72. package/components/u-gap/u-gap.vue +50 -50
  73. package/components/u-grid/types.ts +29 -29
  74. package/components/u-grid/u-grid.vue +91 -91
  75. package/components/u-grid-item/types.ts +24 -24
  76. package/components/u-grid-item/u-grid-item.vue +130 -130
  77. package/components/u-icon/types.ts +69 -69
  78. package/components/u-icon/u-icon.vue +301 -301
  79. package/components/u-image/types.ts +61 -61
  80. package/components/u-image/u-image.vue +245 -245
  81. package/components/u-index-anchor/types.ts +24 -24
  82. package/components/u-index-anchor/u-index-anchor.vue +120 -120
  83. package/components/u-index-list/types.ts +44 -44
  84. package/components/u-index-list/u-index-list.vue +346 -346
  85. package/components/u-input/types.ts +165 -165
  86. package/components/u-input/u-input.vue +453 -453
  87. package/components/u-keyboard/types.ts +40 -40
  88. package/components/u-keyboard/u-keyboard.vue +201 -201
  89. package/components/u-lazy-load/types.ts +37 -37
  90. package/components/u-lazy-load/u-lazy-load.vue +246 -246
  91. package/components/u-line/types.ts +44 -44
  92. package/components/u-line/u-line.vue +68 -68
  93. package/components/u-line-progress/types.ts +58 -58
  94. package/components/u-line-progress/u-line-progress.vue +131 -131
  95. package/components/u-link/types.ts +54 -54
  96. package/components/u-link/u-link.vue +100 -100
  97. package/components/u-loading/types.ts +45 -45
  98. package/components/u-loading/u-loading.vue +106 -106
  99. package/components/u-loading-popup/types.ts +26 -26
  100. package/components/u-loading-popup/u-loading-popup.vue +254 -254
  101. package/components/u-loadmore/types.ts +88 -88
  102. package/components/u-loadmore/u-loadmore.vue +170 -170
  103. package/components/u-mask/types.ts +48 -48
  104. package/components/u-mask/u-mask.vue +113 -113
  105. package/components/u-message-input/types.ts +90 -90
  106. package/components/u-message-input/u-message-input.vue +283 -283
  107. package/components/u-modal/service.ts +48 -48
  108. package/components/u-modal/types.ts +139 -139
  109. package/components/u-modal/u-modal.vue +465 -465
  110. package/components/u-navbar/types.ts +104 -104
  111. package/components/u-navbar/u-navbar.vue +268 -268
  112. package/components/u-no-network/image.ts +2 -2
  113. package/components/u-no-network/types.ts +29 -29
  114. package/components/u-no-network/u-no-network.vue +313 -313
  115. package/components/u-notice-bar/types.ts +111 -111
  116. package/components/u-notice-bar/u-notice-bar.vue +191 -191
  117. package/components/u-number-box/types.ts +42 -42
  118. package/components/u-number-box/u-number-box.vue +322 -322
  119. package/components/u-number-keyboard/types.ts +26 -26
  120. package/components/u-number-keyboard/u-number-keyboard.vue +189 -189
  121. package/components/u-pagination/types.ts +38 -38
  122. package/components/u-pagination/u-pagination.vue +102 -102
  123. package/components/u-picker/types.ts +140 -140
  124. package/components/u-picker/u-picker.vue +854 -854
  125. package/components/u-popup/types.ts +64 -64
  126. package/components/u-popup/u-popup.vue +427 -427
  127. package/components/u-radio/types.ts +39 -39
  128. package/components/u-radio/u-radio.vue +349 -349
  129. package/components/u-radio-group/types.ts +40 -40
  130. package/components/u-radio-group/u-radio-group.vue +96 -96
  131. package/components/u-rate/types.ts +50 -50
  132. package/components/u-rate/u-rate.vue +250 -250
  133. package/components/u-read-more/types.ts +46 -46
  134. package/components/u-read-more/u-read-more.vue +182 -182
  135. package/components/u-root-portal/u-root-portal.vue +55 -55
  136. package/components/u-row/types.ts +30 -30
  137. package/components/u-row/u-row.vue +105 -105
  138. package/components/u-row-notice/types.ts +49 -49
  139. package/components/u-row-notice/u-row-notice.vue +257 -257
  140. package/components/u-safe-bottom/types.ts +19 -19
  141. package/components/u-safe-bottom/u-safe-bottom.vue +55 -55
  142. package/components/u-search/u-search.vue +297 -297
  143. package/components/u-section/types.ts +42 -42
  144. package/components/u-section/u-section.vue +156 -156
  145. package/components/u-select/types.ts +56 -56
  146. package/components/u-select/u-select.vue +447 -447
  147. package/components/u-skeleton/types.ts +89 -89
  148. package/components/u-skeleton/u-skeleton.vue +253 -253
  149. package/components/u-slider/types.ts +55 -55
  150. package/components/u-slider/u-slider.vue +422 -422
  151. package/components/u-status-bar/types.ts +21 -21
  152. package/components/u-status-bar/u-status-bar.vue +64 -64
  153. package/components/u-step/types.ts +37 -37
  154. package/components/u-step/u-step.vue +292 -292
  155. package/components/u-steps/types.ts +39 -39
  156. package/components/u-steps/u-steps.vue +105 -105
  157. package/components/u-sticky/types.ts +33 -33
  158. package/components/u-sticky/u-sticky.vue +177 -177
  159. package/components/u-subsection/types.ts +46 -46
  160. package/components/u-subsection/u-subsection.vue +358 -358
  161. package/components/u-swipe-action/types.ts +60 -60
  162. package/components/u-swipe-action/u-swipe-action.vue +276 -276
  163. package/components/u-swiper/types.ts +57 -57
  164. package/components/u-swiper/u-swiper.vue +308 -308
  165. package/components/u-switch/types.ts +39 -39
  166. package/components/u-switch/u-switch.vue +212 -212
  167. package/components/u-tabbar/types.ts +57 -57
  168. package/components/u-tabbar/u-tabbar.vue +480 -480
  169. package/components/u-table/types.ts +35 -35
  170. package/components/u-table/u-table.vue +67 -67
  171. package/components/u-tabs/types.ts +64 -64
  172. package/components/u-tabs/u-tabs.vue +328 -328
  173. package/components/u-tabs-swiper/types.ts +64 -64
  174. package/components/u-tabs-swiper/u-tabs-swiper.vue +407 -407
  175. package/components/u-tag/types.ts +47 -47
  176. package/components/u-tag/u-tag.vue +276 -276
  177. package/components/u-td/types.ts +22 -22
  178. package/components/u-td/u-td.vue +65 -65
  179. package/components/u-text/types.ts +80 -80
  180. package/components/u-text/u-text.vue +355 -355
  181. package/components/u-textarea/types.ts +105 -105
  182. package/components/u-textarea/u-textarea.vue +450 -450
  183. package/components/u-th/types.ts +22 -22
  184. package/components/u-th/u-th.vue +63 -63
  185. package/components/u-time-line/u-time-line.vue +64 -64
  186. package/components/u-time-line-item/types.ts +24 -24
  187. package/components/u-time-line-item/u-time-line-item.vue +89 -89
  188. package/components/u-toast/service.ts +40 -40
  189. package/components/u-toast/types.ts +54 -54
  190. package/components/u-toast/u-toast.vue +385 -385
  191. package/components/u-top-tips/types.ts +25 -25
  192. package/components/u-top-tips/u-top-tips.vue +130 -130
  193. package/components/u-tr/types.ts +19 -19
  194. package/components/u-tr/u-tr.vue +39 -39
  195. package/components/u-transition/types.ts +43 -43
  196. package/components/u-transition/u-transition.vue +437 -437
  197. package/components/u-upload/types.ts +171 -171
  198. package/components/u-upload/u-upload.vue +1605 -1605
  199. package/components/u-verification-code/types.ts +32 -32
  200. package/components/u-verification-code/u-verification-code.vue +183 -183
  201. package/components/u-waterfall/types.ts +26 -26
  202. package/components/u-waterfall/u-waterfall.vue +188 -188
  203. package/iconfont.css +913 -913
  204. package/index.scss +26 -26
  205. package/libs/config/color.ts +9 -9
  206. package/libs/config/config.ts +59 -59
  207. package/libs/config/theme-tokens.ts +102 -102
  208. package/libs/config/zIndex.ts +32 -32
  209. package/libs/css/color.scss +155 -155
  210. package/libs/css/common.scss +183 -183
  211. package/libs/css/style.components.scss +16 -16
  212. package/libs/css/style.h5.scss +8 -8
  213. package/libs/css/style.mp.scss +68 -68
  214. package/libs/css/style.nvue.scss +15 -15
  215. package/libs/css/style.theme.scss +56 -56
  216. package/libs/css/style.vue.scss +188 -188
  217. package/libs/function/$parent.ts +24 -24
  218. package/libs/function/addUnit.ts +50 -50
  219. package/libs/function/clipboard.ts +73 -73
  220. package/libs/function/color.ts +28 -28
  221. package/libs/function/colorGradient.ts +139 -139
  222. package/libs/function/debounce.ts +28 -28
  223. package/libs/function/deepClone.ts +39 -39
  224. package/libs/function/deepMerge.ts +35 -35
  225. package/libs/function/getParent.ts +63 -63
  226. package/libs/function/getRect.ts +26 -26
  227. package/libs/function/guid.ts +42 -42
  228. package/libs/function/md5.ts +403 -403
  229. package/libs/function/parent.ts +21 -21
  230. package/libs/function/queryParams.ts +64 -64
  231. package/libs/function/random.ts +16 -16
  232. package/libs/function/randomArray.ts +11 -11
  233. package/libs/function/route.ts +118 -118
  234. package/libs/function/styleUtils.ts +83 -83
  235. package/libs/function/sys.ts +15 -15
  236. package/libs/function/test.ts +289 -289
  237. package/libs/function/throttle.ts +31 -31
  238. package/libs/function/timeFormat.ts +55 -55
  239. package/libs/function/timeFrom.ts +48 -48
  240. package/libs/function/toast.ts +14 -14
  241. package/libs/function/trim.ts +21 -21
  242. package/libs/function/type2icon.ts +38 -38
  243. package/libs/hooks/index.ts +10 -10
  244. package/libs/hooks/useColor.ts +61 -61
  245. package/libs/hooks/useCompRelation.ts +424 -424
  246. package/libs/hooks/useDebounce.ts +15 -15
  247. package/libs/hooks/useEmitter.ts +79 -79
  248. package/libs/hooks/useLocale.ts +34 -34
  249. package/libs/hooks/useModal.ts +131 -131
  250. package/libs/hooks/useRect.ts +40 -40
  251. package/libs/hooks/useRouter.ts +173 -173
  252. package/libs/hooks/useTheme.ts +173 -173
  253. package/libs/hooks/useThrottle.ts +16 -16
  254. package/libs/hooks/useToast.ts +115 -115
  255. package/libs/index.ts +349 -349
  256. package/libs/request/auto-http.ts +76 -76
  257. package/libs/request/index.ts +301 -301
  258. package/libs/store/index.ts +88 -88
  259. package/libs/util/async-validator.d.ts +75 -75
  260. package/libs/util/async-validator.js +1 -1
  261. package/libs/util/calendar.d.ts +57 -57
  262. package/libs/util/canvas-2d.ts +182 -182
  263. package/libs/util/config-provider.ts +804 -804
  264. package/libs/util/emitter.ts +112 -112
  265. package/libs/util/mitt.ts +118 -118
  266. package/libs/util/system-theme.ts +25 -25
  267. package/locale/index.ts +2 -2
  268. package/locale/lang/en-US.ts +136 -136
  269. package/locale/lang/zh-CN.ts +136 -136
  270. package/package.json +1 -1
  271. package/plugins/root/page.ts +77 -77
  272. package/plugins/root/root.ts +53 -53
  273. package/theme.scss +149 -149
  274. package/types/components.d.ts +105 -105
  275. package/types/global.d.ts +470 -470
  276. package/types/ignore-errors.d.ts +30 -30
  277. package/types/index.d.ts +15 -15
  278. package/types/uni-app.d.ts +63 -63
@@ -1,346 +1,346 @@
1
- <template>
2
- <!-- 支付宝小程序使用$u.getRect()获取组件的根元素尺寸,所以在外面套一个"壳" -->
3
- <view>
4
- <view class="u-index-bar">
5
- <slot />
6
- <view
7
- v-if="showSidebar"
8
- class="u-index-bar__sidebar"
9
- @touchstart.stop.prevent="onTouchMove"
10
- @touchmove.stop.prevent="onTouchMove"
11
- @touchend.stop.prevent="onTouchStop"
12
- @touchcancel.stop.prevent="onTouchStop"
13
- >
14
- <view
15
- v-for="(item, index) in indexList"
16
- :key="index"
17
- class="u-index-bar__index"
18
- :style="{ zIndex: Number(zIndex) + 1, color: activeAnchorIndex === index ? activeColor : '' }"
19
- :data-index="index"
20
- >
21
- {{ item }}
22
- </view>
23
- </view>
24
- <view
25
- class="u-indexed-list-alert"
26
- v-if="touchmove && indexList[touchmoveIndex]"
27
- :style="{
28
- zIndex: alertZIndex
29
- }"
30
- >
31
- <text>{{ indexList[touchmoveIndex] }}</text>
32
- </view>
33
- </view>
34
- </view>
35
- </template>
36
-
37
- <script lang="ts">
38
- export default {
39
- name: 'u-index-list',
40
- options: {
41
- addGlobalClass: true,
42
- // #ifndef MP-TOUTIAO
43
- virtualHost: true,
44
- // #endif
45
- styleIsolation: 'shared'
46
- }
47
- };
48
- </script>
49
-
50
- <script setup lang="ts">
51
- import { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue';
52
- import { $u, useParent } from '../..';
53
- import { IndexListProps } from './types';
54
-
55
- /**
56
- * indexList 索引列表
57
- * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用
58
- * @tutorial https://uviewpro.cn/zh/components/indexList.html#indexanchor-props
59
- * @property {Number|String} scroll-top 当前滚动高度,自定义组件无法获得滚动条事件,所以依赖接入方传入
60
- * @property {Array} index-list 索引字符列表,数组(默认A-Z)
61
- * @property {Number|String} z-index 锚点吸顶时的层级(默认965)
62
- * @property {Boolean} sticky 是否开启锚点自动吸顶(默认true)
63
- * @property {Number|String} offset-top 锚点自动吸顶时与顶部的距离(默认0)
64
- * @property {String} highlight-color 锚点和右边索引字符高亮颜色(默认主题色primary)
65
- * @event {Function} select 选中右边索引字符时触发
66
- * @example <u-index-list :scrollTop="scrollTop"></u-index-list>
67
- */
68
- const props = defineProps(IndexListProps);
69
- const emit = defineEmits(['select']);
70
- const instance = getCurrentInstance();
71
-
72
- // 索引列表生成函数
73
- function getIndexList() {
74
- const indexList: string[] = [];
75
- const charCodeOfA = 'A'.charCodeAt(0);
76
- for (let i = 0; i < 26; i++) {
77
- indexList.push(String.fromCharCode(charCodeOfA + i));
78
- }
79
- return indexList;
80
- }
81
-
82
- // 变量定义
83
- const activeAnchorIndex = ref(0);
84
- const showSidebar = ref(true);
85
- const touchmove = ref(false);
86
- const touchmoveIndex = ref(0);
87
- const sidebar = reactive<{ height: number; top: number }>({ height: 0, top: 0 });
88
- const scrollToAnchorIndex = ref<number | null>(null);
89
- const timer = ref<any>(null);
90
- const top = ref(0);
91
- const height = ref(0);
92
- const stickyOffsetTop = ref(0);
93
-
94
- // 计算属性
95
- // 弹出toast的z-index值
96
- const alertZIndex = computed(() => $u.zIndex.toast).value;
97
- // indexList 响应式
98
- const indexList = computed(() => props?.indexList ?? getIndexList());
99
- const zIndex = computed(() => props.zIndex).value;
100
- const activeColor = computed(() => props.activeColor).value;
101
-
102
- const { children, broadcast } = useParent('u-index-anchor');
103
-
104
- // 兼容 H5/非H5 stickyOffsetTop
105
- onMounted(() => {
106
- const offsetTopNum = typeof props.offsetTop === 'string' ? Number(props.offsetTop) : props.offsetTop;
107
- // #ifdef H5
108
- stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 44;
109
- // #endif
110
- // #ifndef H5
111
- stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 0;
112
- // #endif
113
- });
114
-
115
- // 监听 scrollTop
116
- watch(
117
- () => props.scrollTop,
118
- () => {
119
- updateData();
120
- }
121
- );
122
-
123
- function updateData() {
124
- if (timer.value) clearTimeout(timer.value);
125
- timer.value = setTimeout(() => {
126
- showSidebar.value = !!children.length;
127
- setRect().then(() => {
128
- onScroll();
129
- });
130
- }, 0);
131
- }
132
-
133
- /**
134
- * 获取各区域尺寸
135
- */
136
- function setRect() {
137
- return Promise.all([setAnchorsRect(), setListRect(), setSiderbarRect()]);
138
- }
139
-
140
- /**
141
- * 获取锚点尺寸
142
- */
143
- function setAnchorsRect() {
144
- return Promise.all(
145
- children.map((anchor, index) => {
146
- $u.getRect('.u-index-anchor-wrapper', anchor.getInstance()).then((rect: any) => {
147
- broadcast('setTop', rect.top, anchor.id);
148
- broadcast('setHeight', rect.height, anchor.id);
149
- });
150
- })
151
- );
152
- }
153
-
154
- /**
155
- * 获取列表尺寸
156
- */
157
- function setListRect() {
158
- return $u.getRect('.u-index-bar', instance).then((rect: any) => {
159
- height.value = rect.height;
160
- top.value = rect.top + Number(props.scrollTop);
161
- });
162
- }
163
-
164
- /**
165
- * 获取侧边栏尺寸
166
- */
167
- function setSiderbarRect() {
168
- return $u.getRect('.u-index-bar__sidebar', instance).then((rect: any) => {
169
- sidebar.height = rect.height;
170
- sidebar.top = rect.top;
171
- });
172
- }
173
-
174
- /**
175
- * 获取当前激活锚点索引
176
- */
177
- function getActiveAnchorIndex() {
178
- const sticky = props.sticky;
179
- for (let i = children.length - 1; i >= 0; i--) {
180
- const preAnchorHeight = i > 0 ? children[i - 1].getExposed().height.value : 0;
181
- const reachTop = sticky ? preAnchorHeight : 0;
182
- if (reachTop >= children[i].getExposed().top.value) {
183
- return i;
184
- }
185
- }
186
- return -1;
187
- }
188
-
189
- /**
190
- * 滚动时处理锚点吸顶和样式
191
- */
192
- function onScroll() {
193
- if (!children.length) return;
194
- const sticky = props.sticky;
195
- const scrollTopNum = Number(props.scrollTop);
196
- const active = getActiveAnchorIndex();
197
- activeAnchorIndex.value = active;
198
- if (sticky) {
199
- let isActiveAnchorSticky = false;
200
- if (active !== -1) {
201
- isActiveAnchorSticky = children[active].getExposed().top.value <= 0;
202
- }
203
- children.forEach((item, index) => {
204
- if (index === active) {
205
- let wrapperStyle: any = '';
206
- let anchorStyle: any = {
207
- color: `${activeColor}`
208
- };
209
- if (isActiveAnchorSticky) {
210
- wrapperStyle = { height: `${children[index].getExposed().height.value}px` };
211
- anchorStyle = {
212
- position: 'fixed',
213
- top: `${stickyOffsetTop.value}px`,
214
- zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,
215
- color: `${activeColor}`
216
- };
217
- }
218
- broadcast('setActive', active, item.id);
219
- broadcast('setAnchorStyle', anchorStyle, item.id);
220
- broadcast('setWrapperStyle', wrapperStyle, item.id);
221
- } else if (index === active - 1) {
222
- const currentAnchor = children[index];
223
- const currentOffsetTop = currentAnchor.getExposed().top.value;
224
- const targetOffsetTop =
225
- index === children.length - 1 ? top.value : children[index + 1].getExposed().top.value;
226
- const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
227
- const translateY = parentOffsetHeight - currentAnchor.getExposed().height.value;
228
- const anchorStyle = {
229
- position: 'relative',
230
- transform: `translate3d(0, ${translateY}px, 0)`,
231
- zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,
232
- color: `${activeColor}`
233
- };
234
- broadcast('setActive', active, currentAnchor.id);
235
- broadcast('setAnchorStyle', anchorStyle, currentAnchor.id);
236
- broadcast('setWrapperStyle', '', item.id);
237
- } else {
238
- broadcast('setActive', false, item.id);
239
- broadcast('setAnchorStyle', '', item.id);
240
- broadcast('setWrapperStyle', '', item.id);
241
- }
242
- });
243
- }
244
- }
245
-
246
- /**
247
- * 侧边栏触摸移动
248
- */
249
- function onTouchMove(event: TouchEvent) {
250
- touchmove.value = true;
251
- const sidebarLength = indexList.value.length;
252
- const touch = event.touches[0];
253
- const itemHeight = sidebar.height / sidebarLength;
254
- let clientY = touch.clientY;
255
- let index = Math.floor((clientY - sidebar.top) / itemHeight);
256
- if (index < 0) {
257
- index = 0;
258
- } else if (index > sidebarLength - 1) {
259
- index = sidebarLength - 1;
260
- }
261
- touchmoveIndex.value = index;
262
- scrollToAnchor(index);
263
- }
264
-
265
- /**
266
- * 侧边栏触摸结束
267
- */
268
- function onTouchStop() {
269
- touchmove.value = false;
270
- scrollToAnchorIndex.value = null;
271
- }
272
-
273
- /**
274
- * 滚动到指定锚点
275
- */
276
- function scrollToAnchor(index: number) {
277
- if (scrollToAnchorIndex.value === index) {
278
- return;
279
- }
280
- scrollToAnchorIndex.value = index;
281
- const anchor = children.find(item => item.getExposed().props.index === indexList.value[index]);
282
- if (anchor) {
283
- emit('select', anchor.getExposed().props.index);
284
- uni.pageScrollTo({
285
- duration: 0,
286
- scrollTop: anchor.getExposed().top.value + Number(props.scrollTop)
287
- });
288
- }
289
- }
290
-
291
- defineExpose({
292
- updateData,
293
- setRect,
294
- onScroll,
295
- children
296
- });
297
- </script>
298
-
299
- <style lang="scss" scoped>
300
- @import '../../libs/css/style.components.scss';
301
-
302
- .u-index-bar {
303
- position: relative;
304
- }
305
-
306
- .u-index-bar__sidebar {
307
- position: fixed;
308
- top: 50%;
309
- right: 0;
310
- @include vue-flex;
311
- flex-direction: column;
312
- text-align: center;
313
- transform: translateY(-50%);
314
- user-select: none;
315
- z-index: 99;
316
- }
317
-
318
- .u-index-bar__index {
319
- font-weight: 500;
320
- padding: 8rpx 18rpx;
321
- font-size: 22rpx;
322
- line-height: 1;
323
- }
324
-
325
- .u-indexed-list-alert {
326
- position: fixed;
327
- width: 120rpx;
328
- height: 120rpx;
329
- right: 90rpx;
330
- top: 50%;
331
- margin-top: -60rpx;
332
- border-radius: 24rpx;
333
- font-size: 50rpx;
334
- color: var(--u-white-color);
335
- background-color: rgba(0, 0, 0, 0.65);
336
- @include vue-flex;
337
- justify-content: center;
338
- align-items: center;
339
- padding: 0;
340
- z-index: 9999999;
341
- }
342
-
343
- .u-indexed-list-alert text {
344
- line-height: 50rpx;
345
- }
346
- </style>
1
+ <template>
2
+ <!-- 支付宝小程序使用$u.getRect()获取组件的根元素尺寸,所以在外面套一个"壳" -->
3
+ <view>
4
+ <view class="u-index-bar">
5
+ <slot />
6
+ <view
7
+ v-if="showSidebar"
8
+ class="u-index-bar__sidebar"
9
+ @touchstart.stop.prevent="onTouchMove"
10
+ @touchmove.stop.prevent="onTouchMove"
11
+ @touchend.stop.prevent="onTouchStop"
12
+ @touchcancel.stop.prevent="onTouchStop"
13
+ >
14
+ <view
15
+ v-for="(item, index) in indexList"
16
+ :key="index"
17
+ class="u-index-bar__index"
18
+ :style="{ zIndex: Number(zIndex) + 1, color: activeAnchorIndex === index ? activeColor : '' }"
19
+ :data-index="index"
20
+ >
21
+ {{ item }}
22
+ </view>
23
+ </view>
24
+ <view
25
+ class="u-indexed-list-alert"
26
+ v-if="touchmove && indexList[touchmoveIndex]"
27
+ :style="{
28
+ zIndex: alertZIndex
29
+ }"
30
+ >
31
+ <text>{{ indexList[touchmoveIndex] }}</text>
32
+ </view>
33
+ </view>
34
+ </view>
35
+ </template>
36
+
37
+ <script lang="ts">
38
+ export default {
39
+ name: 'u-index-list',
40
+ options: {
41
+ addGlobalClass: true,
42
+ // #ifndef MP-TOUTIAO
43
+ virtualHost: true,
44
+ // #endif
45
+ styleIsolation: 'shared'
46
+ }
47
+ };
48
+ </script>
49
+
50
+ <script setup lang="ts">
51
+ import { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue';
52
+ import { $u, useParent } from '../..';
53
+ import { IndexListProps } from './types';
54
+
55
+ /**
56
+ * indexList 索引列表
57
+ * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用
58
+ * @tutorial https://uviewpro.cn/zh/components/indexList.html#indexanchor-props
59
+ * @property {Number|String} scroll-top 当前滚动高度,自定义组件无法获得滚动条事件,所以依赖接入方传入
60
+ * @property {Array} index-list 索引字符列表,数组(默认A-Z)
61
+ * @property {Number|String} z-index 锚点吸顶时的层级(默认965)
62
+ * @property {Boolean} sticky 是否开启锚点自动吸顶(默认true)
63
+ * @property {Number|String} offset-top 锚点自动吸顶时与顶部的距离(默认0)
64
+ * @property {String} highlight-color 锚点和右边索引字符高亮颜色(默认主题色primary)
65
+ * @event {Function} select 选中右边索引字符时触发
66
+ * @example <u-index-list :scrollTop="scrollTop"></u-index-list>
67
+ */
68
+ const props = defineProps(IndexListProps);
69
+ const emit = defineEmits(['select']);
70
+ const instance = getCurrentInstance();
71
+
72
+ // 索引列表生成函数
73
+ function getIndexList() {
74
+ const indexList: string[] = [];
75
+ const charCodeOfA = 'A'.charCodeAt(0);
76
+ for (let i = 0; i < 26; i++) {
77
+ indexList.push(String.fromCharCode(charCodeOfA + i));
78
+ }
79
+ return indexList;
80
+ }
81
+
82
+ // 变量定义
83
+ const activeAnchorIndex = ref(0);
84
+ const showSidebar = ref(true);
85
+ const touchmove = ref(false);
86
+ const touchmoveIndex = ref(0);
87
+ const sidebar = reactive<{ height: number; top: number }>({ height: 0, top: 0 });
88
+ const scrollToAnchorIndex = ref<number | null>(null);
89
+ const timer = ref<any>(null);
90
+ const top = ref(0);
91
+ const height = ref(0);
92
+ const stickyOffsetTop = ref(0);
93
+
94
+ // 计算属性
95
+ // 弹出toast的z-index值
96
+ const alertZIndex = computed(() => $u.zIndex.toast).value;
97
+ // indexList 响应式
98
+ const indexList = computed(() => props?.indexList ?? getIndexList());
99
+ const zIndex = computed(() => props.zIndex).value;
100
+ const activeColor = computed(() => props.activeColor).value;
101
+
102
+ const { children, broadcast } = useParent('u-index-anchor');
103
+
104
+ // 兼容 H5/非H5 stickyOffsetTop
105
+ onMounted(() => {
106
+ const offsetTopNum = typeof props.offsetTop === 'string' ? Number(props.offsetTop) : props.offsetTop;
107
+ // #ifdef H5
108
+ stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 44;
109
+ // #endif
110
+ // #ifndef H5
111
+ stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 0;
112
+ // #endif
113
+ });
114
+
115
+ // 监听 scrollTop
116
+ watch(
117
+ () => props.scrollTop,
118
+ () => {
119
+ updateData();
120
+ }
121
+ );
122
+
123
+ function updateData() {
124
+ if (timer.value) clearTimeout(timer.value);
125
+ timer.value = setTimeout(() => {
126
+ showSidebar.value = !!children.length;
127
+ setRect().then(() => {
128
+ onScroll();
129
+ });
130
+ }, 0);
131
+ }
132
+
133
+ /**
134
+ * 获取各区域尺寸
135
+ */
136
+ function setRect() {
137
+ return Promise.all([setAnchorsRect(), setListRect(), setSiderbarRect()]);
138
+ }
139
+
140
+ /**
141
+ * 获取锚点尺寸
142
+ */
143
+ function setAnchorsRect() {
144
+ return Promise.all(
145
+ children.map((anchor, index) => {
146
+ $u.getRect('.u-index-anchor-wrapper', anchor.getInstance()).then((rect: any) => {
147
+ broadcast('setTop', rect.top, anchor.id);
148
+ broadcast('setHeight', rect.height, anchor.id);
149
+ });
150
+ })
151
+ );
152
+ }
153
+
154
+ /**
155
+ * 获取列表尺寸
156
+ */
157
+ function setListRect() {
158
+ return $u.getRect('.u-index-bar', instance).then((rect: any) => {
159
+ height.value = rect.height;
160
+ top.value = rect.top + Number(props.scrollTop);
161
+ });
162
+ }
163
+
164
+ /**
165
+ * 获取侧边栏尺寸
166
+ */
167
+ function setSiderbarRect() {
168
+ return $u.getRect('.u-index-bar__sidebar', instance).then((rect: any) => {
169
+ sidebar.height = rect.height;
170
+ sidebar.top = rect.top;
171
+ });
172
+ }
173
+
174
+ /**
175
+ * 获取当前激活锚点索引
176
+ */
177
+ function getActiveAnchorIndex() {
178
+ const sticky = props.sticky;
179
+ for (let i = children.length - 1; i >= 0; i--) {
180
+ const preAnchorHeight = i > 0 ? children[i - 1].getExposed().height.value : 0;
181
+ const reachTop = sticky ? preAnchorHeight : 0;
182
+ if (reachTop >= children[i].getExposed().top.value) {
183
+ return i;
184
+ }
185
+ }
186
+ return -1;
187
+ }
188
+
189
+ /**
190
+ * 滚动时处理锚点吸顶和样式
191
+ */
192
+ function onScroll() {
193
+ if (!children.length) return;
194
+ const sticky = props.sticky;
195
+ const scrollTopNum = Number(props.scrollTop);
196
+ const active = getActiveAnchorIndex();
197
+ activeAnchorIndex.value = active;
198
+ if (sticky) {
199
+ let isActiveAnchorSticky = false;
200
+ if (active !== -1) {
201
+ isActiveAnchorSticky = children[active].getExposed().top.value <= 0;
202
+ }
203
+ children.forEach((item, index) => {
204
+ if (index === active) {
205
+ let wrapperStyle: any = '';
206
+ let anchorStyle: any = {
207
+ color: `${activeColor}`
208
+ };
209
+ if (isActiveAnchorSticky) {
210
+ wrapperStyle = { height: `${children[index].getExposed().height.value}px` };
211
+ anchorStyle = {
212
+ position: 'fixed',
213
+ top: `${stickyOffsetTop.value}px`,
214
+ zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,
215
+ color: `${activeColor}`
216
+ };
217
+ }
218
+ broadcast('setActive', active, item.id);
219
+ broadcast('setAnchorStyle', anchorStyle, item.id);
220
+ broadcast('setWrapperStyle', wrapperStyle, item.id);
221
+ } else if (index === active - 1) {
222
+ const currentAnchor = children[index];
223
+ const currentOffsetTop = currentAnchor.getExposed().top.value;
224
+ const targetOffsetTop =
225
+ index === children.length - 1 ? top.value : children[index + 1].getExposed().top.value;
226
+ const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
227
+ const translateY = parentOffsetHeight - currentAnchor.getExposed().height.value;
228
+ const anchorStyle = {
229
+ position: 'relative',
230
+ transform: `translate3d(0, ${translateY}px, 0)`,
231
+ zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,
232
+ color: `${activeColor}`
233
+ };
234
+ broadcast('setActive', active, currentAnchor.id);
235
+ broadcast('setAnchorStyle', anchorStyle, currentAnchor.id);
236
+ broadcast('setWrapperStyle', '', item.id);
237
+ } else {
238
+ broadcast('setActive', false, item.id);
239
+ broadcast('setAnchorStyle', '', item.id);
240
+ broadcast('setWrapperStyle', '', item.id);
241
+ }
242
+ });
243
+ }
244
+ }
245
+
246
+ /**
247
+ * 侧边栏触摸移动
248
+ */
249
+ function onTouchMove(event: TouchEvent) {
250
+ touchmove.value = true;
251
+ const sidebarLength = indexList.value.length;
252
+ const touch = event.touches[0];
253
+ const itemHeight = sidebar.height / sidebarLength;
254
+ let clientY = touch.clientY;
255
+ let index = Math.floor((clientY - sidebar.top) / itemHeight);
256
+ if (index < 0) {
257
+ index = 0;
258
+ } else if (index > sidebarLength - 1) {
259
+ index = sidebarLength - 1;
260
+ }
261
+ touchmoveIndex.value = index;
262
+ scrollToAnchor(index);
263
+ }
264
+
265
+ /**
266
+ * 侧边栏触摸结束
267
+ */
268
+ function onTouchStop() {
269
+ touchmove.value = false;
270
+ scrollToAnchorIndex.value = null;
271
+ }
272
+
273
+ /**
274
+ * 滚动到指定锚点
275
+ */
276
+ function scrollToAnchor(index: number) {
277
+ if (scrollToAnchorIndex.value === index) {
278
+ return;
279
+ }
280
+ scrollToAnchorIndex.value = index;
281
+ const anchor = children.find(item => item.getExposed().props.index === indexList.value[index]);
282
+ if (anchor) {
283
+ emit('select', anchor.getExposed().props.index);
284
+ uni.pageScrollTo({
285
+ duration: 0,
286
+ scrollTop: anchor.getExposed().top.value + Number(props.scrollTop)
287
+ });
288
+ }
289
+ }
290
+
291
+ defineExpose({
292
+ updateData,
293
+ setRect,
294
+ onScroll,
295
+ children
296
+ });
297
+ </script>
298
+
299
+ <style lang="scss" scoped>
300
+ @import '../../libs/css/style.components.scss';
301
+
302
+ .u-index-bar {
303
+ position: relative;
304
+ }
305
+
306
+ .u-index-bar__sidebar {
307
+ position: fixed;
308
+ top: 50%;
309
+ right: 0;
310
+ @include vue-flex;
311
+ flex-direction: column;
312
+ text-align: center;
313
+ transform: translateY(-50%);
314
+ user-select: none;
315
+ z-index: 99;
316
+ }
317
+
318
+ .u-index-bar__index {
319
+ font-weight: 500;
320
+ padding: 8rpx 18rpx;
321
+ font-size: 22rpx;
322
+ line-height: 1;
323
+ }
324
+
325
+ .u-indexed-list-alert {
326
+ position: fixed;
327
+ width: 120rpx;
328
+ height: 120rpx;
329
+ right: 90rpx;
330
+ top: 50%;
331
+ margin-top: -60rpx;
332
+ border-radius: 24rpx;
333
+ font-size: 50rpx;
334
+ color: var(--u-white-color);
335
+ background-color: rgba(0, 0, 0, 0.65);
336
+ @include vue-flex;
337
+ justify-content: center;
338
+ align-items: center;
339
+ padding: 0;
340
+ z-index: 9999999;
341
+ }
342
+
343
+ .u-indexed-list-alert text {
344
+ line-height: 50rpx;
345
+ }
346
+ </style>