uview-pro 0.2.4 → 0.3.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 (249) hide show
  1. package/changelog.md +584 -545
  2. package/components/common/props.ts +22 -22
  3. package/components/u-action-sheet/types.ts +37 -35
  4. package/components/u-action-sheet/u-action-sheet.vue +178 -167
  5. package/components/u-alert-tips/types.ts +41 -39
  6. package/components/u-alert-tips/u-alert-tips.vue +238 -223
  7. package/components/u-avatar/types.ts +36 -34
  8. package/components/u-avatar/u-avatar.vue +217 -207
  9. package/components/u-avatar-cropper/types.ts +23 -23
  10. package/components/u-avatar-cropper/u-avatar-cropper.vue +297 -286
  11. package/components/u-avatar-cropper/weCropper.d.ts +62 -62
  12. package/components/u-avatar-cropper/weCropper.js +1281 -1281
  13. package/components/u-avatar-cropper/weCropper.ts +1276 -1276
  14. package/components/u-back-top/types.ts +36 -39
  15. package/components/u-back-top/u-back-top.vue +140 -128
  16. package/components/u-badge/types.ts +38 -36
  17. package/components/u-badge/u-badge.vue +183 -165
  18. package/components/u-button/types.ts +66 -66
  19. package/components/u-button/u-button.vue +579 -566
  20. package/components/u-calendar/types.ts +75 -75
  21. package/components/u-calendar/u-calendar.vue +793 -793
  22. package/components/u-car-keyboard/types.ts +14 -12
  23. package/components/u-car-keyboard/u-car-keyboard.vue +262 -253
  24. package/components/u-card/types.ts +61 -59
  25. package/components/u-card/u-card.vue +209 -194
  26. package/components/u-cell-group/types.ts +19 -17
  27. package/components/u-cell-group/u-cell-group.vue +60 -50
  28. package/components/u-cell-item/types.ts +56 -54
  29. package/components/u-cell-item/u-cell-item.vue +226 -213
  30. package/components/u-checkbox/types.ts +33 -31
  31. package/components/u-checkbox/u-checkbox.vue +282 -283
  32. package/components/u-checkbox-group/types.ts +34 -32
  33. package/components/u-checkbox-group/u-checkbox-group.vue +130 -130
  34. package/components/u-circle-progress/types.ts +54 -52
  35. package/components/u-circle-progress/u-circle-progress.vue +206 -191
  36. package/components/u-city-select/types.ts +22 -20
  37. package/components/u-city-select/u-city-select.vue +276 -264
  38. package/components/u-col/types.ts +32 -30
  39. package/components/u-col/u-col.vue +142 -123
  40. package/components/u-collapse/types.ts +33 -33
  41. package/components/u-collapse/u-collapse.vue +190 -186
  42. package/components/u-collapse-item/types.ts +27 -27
  43. package/components/u-collapse-item/u-collapse-item.vue +290 -285
  44. package/components/u-column-notice/types.ts +50 -48
  45. package/components/u-column-notice/u-column-notice.vue +222 -210
  46. package/components/u-count-down/types.ts +44 -42
  47. package/components/u-count-down/u-count-down.vue +286 -274
  48. package/components/u-count-to/types.ts +34 -32
  49. package/components/u-count-to/u-count-to.vue +266 -248
  50. package/components/u-divider/types.ts +33 -31
  51. package/components/u-divider/u-divider.vue +145 -129
  52. package/components/u-dropdown/types.ts +34 -32
  53. package/components/u-dropdown/u-dropdown.vue +330 -302
  54. package/components/u-dropdown-item/types.ts +29 -27
  55. package/components/u-dropdown-item/u-dropdown-item.vue +120 -128
  56. package/components/u-empty/types.ts +38 -36
  57. package/components/u-empty/u-empty.vue +103 -88
  58. package/components/u-field/types.ts +71 -69
  59. package/components/u-field/u-field.vue +388 -373
  60. package/components/u-form/types.ts +29 -27
  61. package/components/u-form/u-form.vue +130 -136
  62. package/components/u-form-item/types.ts +72 -70
  63. package/components/u-form-item/u-form-item.vue +447 -447
  64. package/components/u-full-screen/types.ts +16 -14
  65. package/components/u-full-screen/u-full-screen.vue +103 -89
  66. package/components/u-gap/types.ts +20 -18
  67. package/components/u-gap/u-gap.vue +50 -40
  68. package/components/u-grid/types.ts +21 -19
  69. package/components/u-grid/u-grid.vue +91 -93
  70. package/components/u-grid-item/types.ts +16 -16
  71. package/components/u-grid-item/u-grid-item.vue +130 -134
  72. package/components/u-icon/types.ts +61 -62
  73. package/components/u-icon/u-icon.vue +296 -294
  74. package/components/u-image/types.ts +51 -51
  75. package/components/u-image/u-image.vue +239 -230
  76. package/components/u-index-anchor/types.ts +16 -16
  77. package/components/u-index-anchor/u-index-anchor.vue +94 -86
  78. package/components/u-index-list/types.ts +43 -43
  79. package/components/u-index-list/u-index-list.vue +352 -355
  80. package/components/u-input/types.ts +137 -140
  81. package/components/u-input/u-input.vue +288 -279
  82. package/components/u-keyboard/types.ts +40 -40
  83. package/components/u-keyboard/u-keyboard.vue +178 -169
  84. package/components/u-lazy-load/types.ts +37 -37
  85. package/components/u-lazy-load/u-lazy-load.vue +246 -235
  86. package/components/u-line/types.ts +44 -44
  87. package/components/u-line/u-line.vue +68 -59
  88. package/components/u-line-progress/types.ts +58 -58
  89. package/components/u-line-progress/u-line-progress.vue +126 -117
  90. package/components/u-link/types.ts +43 -43
  91. package/components/u-link/u-link.vue +84 -75
  92. package/components/u-loading/types.ts +35 -35
  93. package/components/u-loading/u-loading.vue +105 -96
  94. package/components/u-loading-popup/types.ts +26 -26
  95. package/components/u-loading-popup/u-loading-popup.vue +253 -239
  96. package/components/u-loadmore/types.ts +79 -79
  97. package/components/u-loadmore/u-loadmore.vue +156 -145
  98. package/components/u-mask/types.ts +40 -43
  99. package/components/u-mask/u-mask.vue +113 -106
  100. package/components/u-message-input/types.ts +74 -74
  101. package/components/u-message-input/u-message-input.vue +281 -270
  102. package/components/u-modal/types.ts +118 -118
  103. package/components/u-modal/u-modal.vue +220 -211
  104. package/components/u-navbar/types.ts +103 -103
  105. package/components/u-navbar/u-navbar.vue +251 -240
  106. package/components/u-no-network/image.ts +2 -2
  107. package/components/u-no-network/types.ts +28 -28
  108. package/components/u-no-network/u-no-network.vue +303 -292
  109. package/components/u-notice-bar/types.ts +111 -111
  110. package/components/u-notice-bar/u-notice-bar.vue +189 -179
  111. package/components/u-number-box/types.ts +42 -42
  112. package/components/u-number-box/u-number-box.vue +321 -312
  113. package/components/u-number-keyboard/types.ts +26 -26
  114. package/components/u-number-keyboard/u-number-keyboard.vue +188 -179
  115. package/components/u-picker/types.ts +123 -123
  116. package/components/u-picker/u-picker.vue +685 -676
  117. package/components/u-popup/types.ts +59 -59
  118. package/components/u-popup/u-popup.vue +385 -375
  119. package/components/u-radio/types.ts +27 -25
  120. package/components/u-radio/u-radio.vue +279 -272
  121. package/components/u-radio-group/types.ts +31 -29
  122. package/components/u-radio-group/u-radio-group.vue +96 -108
  123. package/components/u-rate/types.ts +42 -40
  124. package/components/u-rate/u-rate.vue +249 -234
  125. package/components/u-read-more/types.ts +37 -35
  126. package/components/u-read-more/u-read-more.vue +172 -156
  127. package/components/u-root-portal/u-root-portal.vue +56 -54
  128. package/components/u-row/types.ts +22 -20
  129. package/components/u-row/u-row.vue +105 -87
  130. package/components/u-row-notice/types.ts +41 -39
  131. package/components/u-row-notice/u-row-notice.vue +256 -244
  132. package/components/u-safe-bottom/u-safe-bottom.vue +57 -46
  133. package/components/u-search/types.ts +55 -53
  134. package/components/u-search/u-search.vue +279 -268
  135. package/components/u-section/types.ts +34 -32
  136. package/components/u-section/u-section.vue +150 -131
  137. package/components/u-select/types.ts +45 -43
  138. package/components/u-select/u-select.vue +388 -378
  139. package/components/u-skeleton/types.ts +22 -20
  140. package/components/u-skeleton/u-skeleton.vue +231 -220
  141. package/components/u-slider/types.ts +34 -32
  142. package/components/u-slider/u-slider.vue +255 -247
  143. package/components/u-status-bar/u-status-bar.vue +74 -65
  144. package/components/u-steps/types.ts +30 -28
  145. package/components/u-steps/u-steps.vue +181 -169
  146. package/components/u-sticky/types.ts +24 -22
  147. package/components/u-sticky/u-sticky.vue +178 -162
  148. package/components/u-subsection/types.ts +38 -36
  149. package/components/u-subsection/u-subsection.vue +339 -328
  150. package/components/u-swipe-action/types.ts +52 -50
  151. package/components/u-swipe-action/u-swipe-action.vue +276 -260
  152. package/components/u-swiper/types.ts +49 -47
  153. package/components/u-swiper/u-swiper.vue +308 -291
  154. package/components/u-switch/types.ts +30 -28
  155. package/components/u-switch/u-switch.vue +150 -141
  156. package/components/u-tabbar/types.ts +38 -36
  157. package/components/u-tabbar/u-tabbar.vue +315 -298
  158. package/components/u-table/types.ts +27 -25
  159. package/components/u-table/u-table.vue +67 -55
  160. package/components/u-tabs/types.ts +53 -51
  161. package/components/u-tabs/u-tabs.vue +302 -291
  162. package/components/u-tabs-swiper/types.ts +55 -53
  163. package/components/u-tabs-swiper/u-tabs-swiper.vue +409 -397
  164. package/components/u-tag/types.ts +39 -37
  165. package/components/u-tag/u-tag.vue +268 -252
  166. package/components/u-td/types.ts +14 -12
  167. package/components/u-td/u-td.vue +98 -87
  168. package/components/u-text/types.ts +72 -72
  169. package/components/u-text/u-text.vue +343 -341
  170. package/components/u-th/types.ts +14 -12
  171. package/components/u-th/u-th.vue +92 -81
  172. package/components/u-time-line/u-time-line.vue +53 -39
  173. package/components/u-time-line-item/types.ts +16 -14
  174. package/components/u-time-line-item/u-time-line-item.vue +90 -78
  175. package/components/u-toast/types.ts +38 -36
  176. package/components/u-toast/u-toast.vue +240 -233
  177. package/components/u-top-tips/types.ts +16 -14
  178. package/components/u-top-tips/u-top-tips.vue +130 -113
  179. package/components/u-tr/types.ts +11 -8
  180. package/components/u-tr/u-tr.vue +39 -24
  181. package/components/u-upload/types.ts +82 -80
  182. package/components/u-upload/u-upload.vue +568 -559
  183. package/components/u-verification-code/types.ts +24 -22
  184. package/components/u-verification-code/u-verification-code.vue +176 -164
  185. package/components/u-waterfall/types.ts +18 -16
  186. package/components/u-waterfall/u-waterfall.vue +187 -175
  187. package/iconfont.css +913 -913
  188. package/index.scss +25 -25
  189. package/index.ts +38 -38
  190. package/libs/config/config.ts +26 -26
  191. package/libs/config/zIndex.ts +37 -37
  192. package/libs/css/color.scss +155 -155
  193. package/libs/css/common.scss +178 -178
  194. package/libs/css/style.components.scss +16 -16
  195. package/libs/css/style.h5.scss +8 -8
  196. package/libs/css/style.mp.scss +72 -72
  197. package/libs/css/style.nvue.scss +15 -15
  198. package/libs/css/style.vue.scss +188 -188
  199. package/libs/function/$parent.ts +24 -24
  200. package/libs/function/addUnit.ts +13 -13
  201. package/libs/function/color.ts +37 -37
  202. package/libs/function/colorGradient.ts +139 -139
  203. package/libs/function/debounce.ts +28 -28
  204. package/libs/function/deepClone.ts +39 -39
  205. package/libs/function/deepMerge.ts +35 -35
  206. package/libs/function/getParent.ts +63 -63
  207. package/libs/function/getRect.ts +26 -26
  208. package/libs/function/guid.ts +42 -42
  209. package/libs/function/md5.ts +403 -403
  210. package/libs/function/parent.ts +21 -21
  211. package/libs/function/queryParams.ts +64 -64
  212. package/libs/function/random.ts +16 -16
  213. package/libs/function/randomArray.ts +11 -11
  214. package/libs/function/route.ts +118 -118
  215. package/libs/function/styleUtils.ts +83 -83
  216. package/libs/function/sys.ts +15 -15
  217. package/libs/function/test.ts +289 -289
  218. package/libs/function/throttle.ts +31 -31
  219. package/libs/function/timeFormat.ts +55 -55
  220. package/libs/function/timeFrom.ts +48 -48
  221. package/libs/function/toast.ts +14 -14
  222. package/libs/function/trim.ts +21 -21
  223. package/libs/function/type2icon.ts +39 -39
  224. package/libs/hooks/index.ts +4 -3
  225. package/libs/hooks/useCompRelation.ts +364 -0
  226. package/libs/hooks/useComponent.ts +759 -759
  227. package/libs/hooks/useEmitter.ts +79 -79
  228. package/libs/hooks/useParent.ts +33 -33
  229. package/libs/hooks/useRect.ts +33 -33
  230. package/libs/index.ts +337 -320
  231. package/libs/request/auto-http.ts +76 -76
  232. package/libs/request/index.ts +242 -242
  233. package/libs/store/index.ts +88 -88
  234. package/libs/util/async-validator.d.ts +75 -75
  235. package/libs/util/async-validator.js +1 -1
  236. package/libs/util/calendar.d.ts +57 -57
  237. package/libs/util/emitter.ts +112 -112
  238. package/libs/util/eventBus.ts +86 -86
  239. package/libs/util/logger.ts +364 -364
  240. package/libs/util/mitt.ts +118 -118
  241. package/libs/util/parent.ts +20 -20
  242. package/package.json +4 -4
  243. package/readme.md +241 -241
  244. package/theme.scss +38 -38
  245. package/types/components.d.ts +97 -97
  246. package/types/global.d.ts +331 -331
  247. package/types/ignore-errors.d.ts +30 -30
  248. package/types/index.d.ts +19 -19
  249. package/types/uni-app.d.ts +63 -63
@@ -1,248 +1,266 @@
1
- <template>
2
- <view
3
- class="u-count-num"
4
- :style="{
5
- fontSize: props.fontSize + 'rpx',
6
- fontWeight: props.bold ? 'bold' : 'normal',
7
- color: props.color
8
- }"
9
- >
10
- {{ displayValue }}
11
- </view>
12
- </template>
13
-
14
- <script setup lang="ts">
15
- import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
16
- import { CountToProps } from './types';
17
-
18
- defineOptions({ name: 'u-count-to' });
19
-
20
- /**
21
- * countTo 数字滚动
22
- * @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
23
- * @tutorial https://uviewpro.cn/zh/components/countTo.html
24
- * @property {String | Number} start-val 开始值
25
- * @property {String | Number} end-val 结束值
26
- * @property {String | Number} duration 滚动过程所需的时间,单位ms(默认2000)
27
- * @property {Boolean} autoplay 是否自动开始滚动(默认true)
28
- * @property {String | Number} decimals 要显示的小数位数,见官网说明(默认0)
29
- * @property {Boolean} use-easing 滚动结束时,是否缓动结尾,见官网说明(默认true)
30
- * @property {String} separator 千位分隔符,见官网说明
31
- * @property {String} color 字体颜色(默认#303133)
32
- * @property {String | Number} font-size 字体大小,单位rpx(默认50)
33
- * @property {Boolean} bold 字体是否加粗(默认false)
34
- * @event {Function} end 数值滚动到目标值时触发
35
- * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
36
- */
37
-
38
- const emit = defineEmits(['end']);
39
-
40
- const props = defineProps(CountToProps);
41
-
42
- const localStartVal = ref(Number(props.startVal));
43
- const displayValue = ref(formatNumber(props.startVal));
44
- const printVal = ref<number | null>(null);
45
- const paused = ref(false); // 是否暂停
46
- const localDuration = ref(Number(props.duration));
47
- const startTime = ref<number | null>(null); // 开始的时间
48
- const timestamp = ref<number | null>(null); // 时间戳
49
- const remaining = ref<number | null>(null); // 停留的时间
50
- const rAF = ref<number | null>(null);
51
- const lastTime = ref(0); // 上一次的时间
52
-
53
- /**
54
- * 是否倒计时
55
- */
56
- const countDown = computed(() => Number(props.startVal) > Number(props.endVal));
57
-
58
- watch(
59
- () => props.startVal,
60
- () => {
61
- if (props.autoplay) start();
62
- }
63
- );
64
- watch(
65
- () => props.endVal,
66
- () => {
67
- if (props.autoplay) start();
68
- }
69
- );
70
-
71
- onMounted(() => {
72
- if (props.autoplay) start();
73
- });
74
-
75
- /**
76
- * 缓动函数
77
- */
78
- function easingFn(t: number, b: number, c: number, d: number): number {
79
- return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
80
- }
81
-
82
- /**
83
- * requestAnimationFrame polyfill
84
- */
85
- function requestAnimationFrame(callback: (ts: number) => void): number {
86
- const currTime = new Date().getTime();
87
- // 为了使setTimteout的尽可能的接近每秒60帧的效果
88
- const timeToCall = Math.max(0, 16 - (currTime - lastTime.value));
89
- const id = setTimeout(() => {
90
- callback(currTime + timeToCall);
91
- }, timeToCall);
92
- lastTime.value = currTime + timeToCall;
93
- return id as unknown as number;
94
- }
95
-
96
- /**
97
- * 取消动画帧
98
- */
99
- function cancelAnimationFrame(id: number | null) {
100
- if (id) clearTimeout(id);
101
- }
102
-
103
- /**
104
- * 开始滚动数字
105
- */
106
- function start() {
107
- localStartVal.value = Number(props.startVal);
108
- startTime.value = null;
109
- localDuration.value = Number(props.duration);
110
- paused.value = false;
111
- rAF.value = requestAnimationFrame(count);
112
- }
113
-
114
- /**
115
- * 暂停/恢复滚动
116
- * 暂定状态,重新再开始滚动;或者滚动状态下,暂停
117
- */
118
- function reStart() {
119
- if (paused.value) {
120
- resume();
121
- paused.value = false;
122
- } else {
123
- stop();
124
- paused.value = true;
125
- }
126
- }
127
-
128
- /**
129
- * 暂停
130
- */
131
- function stop() {
132
- cancelAnimationFrame(rAF.value);
133
- }
134
-
135
- /**
136
- * 重新开始(暂停的情况下)
137
- */
138
- function resume() {
139
- startTime.value = null;
140
- localDuration.value = remaining.value || Number(props.duration);
141
- localStartVal.value = printVal.value || Number(props.startVal);
142
- rAF.value = requestAnimationFrame(count);
143
- }
144
-
145
- /**
146
- * 重置
147
- */
148
- function reset() {
149
- startTime.value = null;
150
- cancelAnimationFrame(rAF.value);
151
- displayValue.value = formatNumber(props.startVal);
152
- }
153
-
154
- /**
155
- * 数字滚动动画主逻辑
156
- */
157
- function count(ts: number) {
158
- if (!startTime.value) startTime.value = ts;
159
- timestamp.value = ts;
160
- const progress = ts - (startTime.value || 0);
161
- remaining.value = localDuration.value - progress;
162
- let val: number;
163
- if (props.useEasing) {
164
- if (countDown.value) {
165
- val =
166
- localStartVal.value -
167
- easingFn(progress, 0, localStartVal.value - Number(props.endVal), localDuration.value);
168
- } else {
169
- val = easingFn(
170
- progress,
171
- localStartVal.value,
172
- Number(props.endVal) - localStartVal.value,
173
- localDuration.value
174
- );
175
- }
176
- } else {
177
- if (countDown.value) {
178
- val = localStartVal.value - (localStartVal.value - Number(props.endVal)) * (progress / localDuration.value);
179
- } else {
180
- val = localStartVal.value + (Number(props.endVal) - localStartVal.value) * (progress / localDuration.value);
181
- }
182
- }
183
- if (countDown.value) {
184
- val = val < Number(props.endVal) ? Number(props.endVal) : val;
185
- } else {
186
- val = val > Number(props.endVal) ? Number(props.endVal) : val;
187
- }
188
- printVal.value = val;
189
- displayValue.value = formatNumber(val);
190
- if (progress < localDuration.value) {
191
- rAF.value = requestAnimationFrame(count);
192
- } else {
193
- emit('end');
194
- }
195
- }
196
-
197
- /**
198
- * 判断是否数字
199
- */
200
- function isNumber(val: unknown): boolean {
201
- return !isNaN(parseFloat(String(val)));
202
- }
203
-
204
- /**
205
- * 格式化数字
206
- */
207
- function formatNumber(num: unknown): string {
208
- // 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
209
- let n = Number(num);
210
- n = Number(n.toFixed(Number(props.decimals)));
211
- let str = n + '';
212
- const x = str.split('.');
213
- let x1 = x[0];
214
- const x2 = x.length > 1 ? String(props.decimal) + x[1] : '';
215
- const rgx = /(\d+)(\d{3})/;
216
- if (props.separator && !isNumber(props.separator)) {
217
- while (rgx.test(x1)) {
218
- x1 = x1.replace(rgx, '$1' + props.separator + '$2');
219
- }
220
- }
221
- return x1 + x2;
222
- }
223
-
224
- // 销毁时清理动画帧
225
- onUnmounted(() => {
226
- cancelAnimationFrame(rAF.value);
227
- });
228
-
229
- // 暴露给父组件的函数
230
- defineExpose({
231
- start,
232
- stop,
233
- reStart,
234
- resume,
235
- reset
236
- });
237
- </script>
238
-
239
- <style lang="scss" scoped>
240
- @import '../../libs/css/style.components.scss';
241
-
242
- .u-count-num {
243
- /* #ifndef APP-NVUE */
244
- display: inline-flex;
245
- /* #endif */
246
- text-align: center;
247
- }
248
- </style>
1
+ <template>
2
+ <view
3
+ class="u-count-num"
4
+ :class="customClass"
5
+ :style="
6
+ $u.toStyle(
7
+ {
8
+ fontSize: props.fontSize + 'rpx',
9
+ fontWeight: props.bold ? 'bold' : 'normal',
10
+ color: props.color
11
+ },
12
+ customStyle
13
+ )
14
+ "
15
+ >
16
+ {{ displayValue }}
17
+ </view>
18
+ </template>
19
+
20
+ <script lang="ts">
21
+ export default {
22
+ name: 'u-count-to',
23
+ options: {
24
+ addGlobalClass: true,
25
+ // #ifndef MP-TOUTIAO
26
+ virtualHost: true,
27
+ // #endif
28
+ styleIsolation: 'shared'
29
+ }
30
+ };
31
+ </script>
32
+
33
+ <script setup lang="ts">
34
+ import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
35
+ import { CountToProps } from './types';
36
+ import { $u } from '../../';
37
+
38
+ /**
39
+ * countTo 数字滚动
40
+ * @description 该组件一般用于需要滚动数字到某一个值的场景,目标要求是一个递增的值。
41
+ * @tutorial https://uviewpro.cn/zh/components/countTo.html
42
+ * @property {String | Number} start-val 开始值
43
+ * @property {String | Number} end-val 结束值
44
+ * @property {String | Number} duration 滚动过程所需的时间,单位ms(默认2000)
45
+ * @property {Boolean} autoplay 是否自动开始滚动(默认true)
46
+ * @property {String | Number} decimals 要显示的小数位数,见官网说明(默认0)
47
+ * @property {Boolean} use-easing 滚动结束时,是否缓动结尾,见官网说明(默认true)
48
+ * @property {String} separator 千位分隔符,见官网说明
49
+ * @property {String} color 字体颜色(默认#303133)
50
+ * @property {String | Number} font-size 字体大小,单位rpx(默认50)
51
+ * @property {Boolean} bold 字体是否加粗(默认false)
52
+ * @event {Function} end 数值滚动到目标值时触发
53
+ * @example <u-count-to ref="uCountTo" :end-val="endVal" :autoplay="autoplay"></u-count-to>
54
+ */
55
+
56
+ const emit = defineEmits(['end']);
57
+
58
+ const props = defineProps(CountToProps);
59
+
60
+ const localStartVal = ref(Number(props.startVal));
61
+ const displayValue = ref(formatNumber(props.startVal));
62
+ const printVal = ref<number | null>(null);
63
+ const paused = ref(false); // 是否暂停
64
+ const localDuration = ref(Number(props.duration));
65
+ const startTime = ref<number | null>(null); // 开始的时间
66
+ const timestamp = ref<number | null>(null); // 时间戳
67
+ const remaining = ref<number | null>(null); // 停留的时间
68
+ const rAF = ref<number | null>(null);
69
+ const lastTime = ref(0); // 上一次的时间
70
+
71
+ /**
72
+ * 是否倒计时
73
+ */
74
+ const countDown = computed(() => Number(props.startVal) > Number(props.endVal));
75
+
76
+ watch(
77
+ () => props.startVal,
78
+ () => {
79
+ if (props.autoplay) start();
80
+ }
81
+ );
82
+ watch(
83
+ () => props.endVal,
84
+ () => {
85
+ if (props.autoplay) start();
86
+ }
87
+ );
88
+
89
+ onMounted(() => {
90
+ if (props.autoplay) start();
91
+ });
92
+
93
+ /**
94
+ * 缓动函数
95
+ */
96
+ function easingFn(t: number, b: number, c: number, d: number): number {
97
+ return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;
98
+ }
99
+
100
+ /**
101
+ * requestAnimationFrame polyfill
102
+ */
103
+ function requestAnimationFrame(callback: (ts: number) => void): number {
104
+ const currTime = new Date().getTime();
105
+ // 为了使setTimteout的尽可能的接近每秒60帧的效果
106
+ const timeToCall = Math.max(0, 16 - (currTime - lastTime.value));
107
+ const id = setTimeout(() => {
108
+ callback(currTime + timeToCall);
109
+ }, timeToCall);
110
+ lastTime.value = currTime + timeToCall;
111
+ return id as unknown as number;
112
+ }
113
+
114
+ /**
115
+ * 取消动画帧
116
+ */
117
+ function cancelAnimationFrame(id: number | null) {
118
+ if (id) clearTimeout(id);
119
+ }
120
+
121
+ /**
122
+ * 开始滚动数字
123
+ */
124
+ function start() {
125
+ localStartVal.value = Number(props.startVal);
126
+ startTime.value = null;
127
+ localDuration.value = Number(props.duration);
128
+ paused.value = false;
129
+ rAF.value = requestAnimationFrame(count);
130
+ }
131
+
132
+ /**
133
+ * 暂停/恢复滚动
134
+ * 暂定状态,重新再开始滚动;或者滚动状态下,暂停
135
+ */
136
+ function reStart() {
137
+ if (paused.value) {
138
+ resume();
139
+ paused.value = false;
140
+ } else {
141
+ stop();
142
+ paused.value = true;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * 暂停
148
+ */
149
+ function stop() {
150
+ cancelAnimationFrame(rAF.value);
151
+ }
152
+
153
+ /**
154
+ * 重新开始(暂停的情况下)
155
+ */
156
+ function resume() {
157
+ startTime.value = null;
158
+ localDuration.value = remaining.value || Number(props.duration);
159
+ localStartVal.value = printVal.value || Number(props.startVal);
160
+ rAF.value = requestAnimationFrame(count);
161
+ }
162
+
163
+ /**
164
+ * 重置
165
+ */
166
+ function reset() {
167
+ startTime.value = null;
168
+ cancelAnimationFrame(rAF.value);
169
+ displayValue.value = formatNumber(props.startVal);
170
+ }
171
+
172
+ /**
173
+ * 数字滚动动画主逻辑
174
+ */
175
+ function count(ts: number) {
176
+ if (!startTime.value) startTime.value = ts;
177
+ timestamp.value = ts;
178
+ const progress = ts - (startTime.value || 0);
179
+ remaining.value = localDuration.value - progress;
180
+ let val: number;
181
+ if (props.useEasing) {
182
+ if (countDown.value) {
183
+ val =
184
+ localStartVal.value -
185
+ easingFn(progress, 0, localStartVal.value - Number(props.endVal), localDuration.value);
186
+ } else {
187
+ val = easingFn(
188
+ progress,
189
+ localStartVal.value,
190
+ Number(props.endVal) - localStartVal.value,
191
+ localDuration.value
192
+ );
193
+ }
194
+ } else {
195
+ if (countDown.value) {
196
+ val = localStartVal.value - (localStartVal.value - Number(props.endVal)) * (progress / localDuration.value);
197
+ } else {
198
+ val = localStartVal.value + (Number(props.endVal) - localStartVal.value) * (progress / localDuration.value);
199
+ }
200
+ }
201
+ if (countDown.value) {
202
+ val = val < Number(props.endVal) ? Number(props.endVal) : val;
203
+ } else {
204
+ val = val > Number(props.endVal) ? Number(props.endVal) : val;
205
+ }
206
+ printVal.value = val;
207
+ displayValue.value = formatNumber(val);
208
+ if (progress < localDuration.value) {
209
+ rAF.value = requestAnimationFrame(count);
210
+ } else {
211
+ emit('end');
212
+ }
213
+ }
214
+
215
+ /**
216
+ * 判断是否数字
217
+ */
218
+ function isNumber(val: unknown): boolean {
219
+ return !isNaN(parseFloat(String(val)));
220
+ }
221
+
222
+ /**
223
+ * 格式化数字
224
+ */
225
+ function formatNumber(num: unknown): string {
226
+ // 将num转为Number类型,因为其值可能为字符串数值,调用toFixed会报错
227
+ let n = Number(num);
228
+ n = Number(n.toFixed(Number(props.decimals)));
229
+ let str = n + '';
230
+ const x = str.split('.');
231
+ let x1 = x[0];
232
+ const x2 = x.length > 1 ? String(props.decimal) + x[1] : '';
233
+ const rgx = /(\d+)(\d{3})/;
234
+ if (props.separator && !isNumber(props.separator)) {
235
+ while (rgx.test(x1)) {
236
+ x1 = x1.replace(rgx, '$1' + props.separator + '$2');
237
+ }
238
+ }
239
+ return x1 + x2;
240
+ }
241
+
242
+ // 销毁时清理动画帧
243
+ onUnmounted(() => {
244
+ cancelAnimationFrame(rAF.value);
245
+ });
246
+
247
+ // 暴露给父组件的函数
248
+ defineExpose({
249
+ start,
250
+ stop,
251
+ reStart,
252
+ resume,
253
+ reset
254
+ });
255
+ </script>
256
+
257
+ <style lang="scss" scoped>
258
+ @import '../../libs/css/style.components.scss';
259
+
260
+ .u-count-num {
261
+ /* #ifndef APP-NVUE */
262
+ display: inline-flex;
263
+ /* #endif */
264
+ text-align: center;
265
+ }
266
+ </style>
@@ -1,31 +1,33 @@
1
- import type { ExtractPropTypes, PropType } from 'vue';
2
- import type { ThemeType } from '../../types/global';
3
-
4
- /**
5
- * u-divider 分割线 Props
6
- * @description 区隔内容的分割线,一般用于页面底部"没有更多"的提示。
7
- */
8
- export const DividerProps = {
9
- /** 单一边divider横线的宽度(数值),单位rpx。或者百分比 */
10
- halfWidth: { type: [Number, String] as PropType<number | string>, default: 150 },
11
- /** divider横线的颜色,如设置 */
12
- borderColor: { type: String, default: '#dcdfe6' },
13
- /** 主题色,可以是primary|info|success|warning|error之一值 */
14
- type: { type: String as PropType<ThemeType>, default: 'primary' },
15
- /** 文字颜色 */
16
- color: { type: String, default: '#909399' },
17
- /** 文字大小,单位rpx */
18
- fontSize: { type: [Number, String] as PropType<number | string>, default: 26 },
19
- /** 整个divider的背景颜色 */
20
- bgColor: { type: String, default: '#ffffff' },
21
- /** 整个divider的高度单位rpx */
22
- height: { type: [Number, String] as PropType<number | string>, default: 'auto' },
23
- /** 上边距 */
24
- marginTop: { type: [String, Number] as PropType<string | number>, default: 0 },
25
- /** 下边距 */
26
- marginBottom: { type: [String, Number] as PropType<string | number>, default: 0 },
27
- /** 是否使用slot传入内容,如果不用slot传入内容,先的中间就不会有空隙 */
28
- useSlot: { type: Boolean, default: true }
29
- };
30
-
31
- export type DividerProps = ExtractPropTypes<typeof DividerProps>;
1
+ import type { ExtractPropTypes, PropType } from 'vue';
2
+ import type { ThemeType } from '../../types/global';
3
+ import { baseProps } from '../common/props';
4
+
5
+ /**
6
+ * u-divider 分割线 Props
7
+ * @description 区隔内容的分割线,一般用于页面底部"没有更多"的提示。
8
+ */
9
+ export const DividerProps = {
10
+ ...baseProps,
11
+ /** 单一边divider横线的宽度(数值),单位rpx。或者百分比 */
12
+ halfWidth: { type: [Number, String] as PropType<number | string>, default: 150 },
13
+ /** divider横线的颜色,如设置 */
14
+ borderColor: { type: String, default: '#dcdfe6' },
15
+ /** 主题色,可以是primary|info|success|warning|error之一值 */
16
+ type: { type: String as PropType<ThemeType>, default: 'primary' },
17
+ /** 文字颜色 */
18
+ color: { type: String, default: '#909399' },
19
+ /** 文字大小,单位rpx */
20
+ fontSize: { type: [Number, String] as PropType<number | string>, default: 26 },
21
+ /** 整个divider的背景颜色 */
22
+ bgColor: { type: String, default: '#ffffff' },
23
+ /** 整个divider的高度单位rpx */
24
+ height: { type: [Number, String] as PropType<number | string>, default: 'auto' },
25
+ /** 上边距 */
26
+ marginTop: { type: [String, Number] as PropType<string | number>, default: 0 },
27
+ /** 下边距 */
28
+ marginBottom: { type: [String, Number] as PropType<string | number>, default: 0 },
29
+ /** 是否使用slot传入内容,如果不用slot传入内容,先的中间就不会有空隙 */
30
+ useSlot: { type: Boolean, default: true }
31
+ };
32
+
33
+ export type DividerProps = ExtractPropTypes<typeof DividerProps>;