hy-app 0.6.8 → 0.7.0

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 (109) hide show
  1. package/attributes.json +1 -1
  2. package/components/hy-action-sheet/index.scss +2 -2
  3. package/components/hy-avatar/hy-avatar.vue +12 -5
  4. package/components/hy-avatar/index.scss +2 -2
  5. package/components/hy-avatar/props.ts +4 -2
  6. package/components/hy-avatar/typing.d.ts +8 -1
  7. package/components/hy-calendar/hy-calendar.vue +1 -0
  8. package/components/hy-calendar/month.vue +25 -5
  9. package/components/hy-calendar/props.ts +1 -1
  10. package/components/hy-cascader/hy-cascader.vue +503 -0
  11. package/components/hy-cascader/index.scss +84 -0
  12. package/components/hy-cascader/props.ts +88 -0
  13. package/components/hy-cascader/typing.d.ts +34 -0
  14. package/components/hy-cell-item/index.scss +8 -9
  15. package/components/hy-check-button/typing.d.ts +12 -7
  16. package/components/hy-code-input/hy-code-input.vue +33 -11
  17. package/components/hy-code-input/index.scss +2 -2
  18. package/components/hy-code-input/typing.d.ts +4 -0
  19. package/components/hy-config-provider/hy-config-provider.vue +58 -53
  20. package/components/hy-config-provider/props.ts +1 -1
  21. package/components/hy-datetime-picker/props.ts +1 -1
  22. package/components/hy-datetime-picker/typing.d.ts +1 -1
  23. package/components/hy-dropdown/typing.d.ts +5 -0
  24. package/components/hy-float-button/index.scss +1 -1
  25. package/components/hy-form/typing.d.ts +6 -0
  26. package/components/hy-form-item/typing.d.ts +1 -1
  27. package/components/hy-grid/hy-grid.vue +12 -12
  28. package/components/hy-grid/index.scss +1 -2
  29. package/components/hy-grid/props.ts +7 -2
  30. package/components/hy-grid/typing.d.ts +1 -1
  31. package/components/hy-icon/typing.d.ts +52 -9
  32. package/components/hy-index-bar/index.scss +1 -1
  33. package/components/hy-keyboard/constants.ts +83 -0
  34. package/components/hy-keyboard/hy-keyboard.vue +375 -0
  35. package/components/hy-keyboard/index.scss +73 -0
  36. package/components/hy-keyboard/key/index.scss +79 -0
  37. package/components/hy-keyboard/key/index.vue +91 -0
  38. package/components/hy-keyboard/key/types.ts +1 -0
  39. package/components/hy-keyboard/props.ts +108 -0
  40. package/components/hy-keyboard/typing.d.ts +18 -0
  41. package/components/hy-line-progress/index.scss +3 -3
  42. package/components/hy-menu/index.scss +1 -1
  43. package/components/hy-modal/index.scss +2 -2
  44. package/components/hy-modal/typing.d.ts +2 -2
  45. package/components/hy-notice-bar/hy-column-notice.vue +54 -94
  46. package/components/hy-notice-bar/hy-notice-bar.vue +128 -96
  47. package/components/hy-notice-bar/hy-row-notice.vue +89 -121
  48. package/components/hy-notice-bar/index.scss +1 -1
  49. package/components/hy-notice-bar/props.ts +86 -85
  50. package/components/hy-notify/hy-notify.vue +9 -9
  51. package/components/hy-notify/typing.d.ts +22 -0
  52. package/components/hy-picker/hy-picker.vue +126 -149
  53. package/components/hy-picker/props.ts +4 -1
  54. package/components/hy-picker/typing.d.ts +22 -0
  55. package/components/hy-popover/index.scss +6 -6
  56. package/components/hy-popup/index.scss +6 -5
  57. package/components/hy-price/hy-price.vue +52 -23
  58. package/components/hy-price/props.ts +54 -54
  59. package/components/hy-radio/props.ts +1 -1
  60. package/components/hy-radio/typing.d.ts +5 -1
  61. package/components/hy-rolling-num/typing.d.ts +1 -0
  62. package/components/hy-scroll-list/index.scss +2 -2
  63. package/components/hy-search/index.scss +1 -1
  64. package/components/hy-signature/index.scss +1 -1
  65. package/components/hy-skeleton/index.scss +21 -4
  66. package/components/hy-slider/index.scss +3 -3
  67. package/components/hy-steps/hy-steps.vue +1 -1
  68. package/components/hy-steps/index.scss +3 -3
  69. package/components/hy-submit-bar/typing.d.ts +3 -3
  70. package/components/hy-subsection/index.scss +8 -8
  71. package/components/hy-swipe-action/hy-swipe-action.vue +34 -15
  72. package/components/hy-swipe-action/index.scss +0 -1
  73. package/components/hy-swiper/index.scss +2 -2
  74. package/components/hy-switch/index.scss +3 -3
  75. package/components/hy-switch/typing.d.ts +4 -0
  76. package/components/hy-tabbar/props.ts +2 -1
  77. package/components/hy-tabbar/typing.d.ts +5 -4
  78. package/components/hy-tabbar-group/index.scss +2 -2
  79. package/components/hy-tabs/hy-tabs.vue +338 -336
  80. package/components/hy-tabs/index.scss +7 -7
  81. package/components/hy-tabs/typing.d.ts +41 -33
  82. package/components/hy-tag/index.scss +1 -1
  83. package/components/hy-textarea/hy-textarea.vue +2 -2
  84. package/components/hy-textarea/index.scss +4 -4
  85. package/components/hy-textarea/typing.d.ts +4 -0
  86. package/components/hy-toast/hy-toast.vue +14 -6
  87. package/components/hy-toast/index.scss +1 -1
  88. package/components/hy-toast/typing.d.ts +42 -36
  89. package/components/hy-tooltip/hy-tooltip.vue +1 -1
  90. package/components/hy-tooltip/index.scss +7 -6
  91. package/components/hy-tooltip/props.ts +1 -1
  92. package/components/hy-upload/hy-upload.vue +16 -1
  93. package/components/hy-upload/index.scss +149 -144
  94. package/components/hy-warn/index.scss +1 -1
  95. package/components/index.ts +6 -0
  96. package/global.d.ts +2 -0
  97. package/libs/config/icon.ts +442 -430
  98. package/libs/css/_function.scss +7 -13
  99. package/libs/css/_mixin.scss +3 -3
  100. package/libs/css/common.scss +1 -1
  101. package/libs/css/iconfont.css +445 -441
  102. package/libs/css/theme.scss +54 -25
  103. package/libs/locale/lang/en-US.ts +4 -0
  104. package/libs/locale/lang/zh-CN.ts +4 -0
  105. package/libs/typing/index.ts +80 -0
  106. package/package.json +5 -2
  107. package/tags.json +1 -1
  108. package/web-types.json +1 -1
  109. package/components/hy-qrcode/qrcode.js.bak +0 -1434
@@ -122,8 +122,8 @@ export default {
122
122
 
123
123
  <script setup lang="ts">
124
124
  import { computed, ref, watch } from 'vue'
125
- import { deepClone, sleep, addUnit, isArray, useTranslate } from '../../libs'
126
- import type { IPickerEmits } from './typing'
125
+ import { addUnit, isArray, useTranslate } from '../../libs'
126
+ import type { IPickerEmits, IPickerExpose, PickerColumnVo } from './typing'
127
127
  import pickerProps from './props'
128
128
  // 组件
129
129
  import HyInput from '../hy-input/hy-input.vue'
@@ -174,26 +174,48 @@ watch(
174
174
  { immediate: true }
175
175
  )
176
176
 
177
+ /**
178
+ * 解析 modelValue 为数组形式
179
+ * @param value 原始值
180
+ * @returns 解析后的数组
181
+ */
182
+ const parseModelValue = (value: string | number | any[]): any[] => {
183
+ if (isArray(value)) {
184
+ return value
185
+ }
186
+ const strValue = String(value)
187
+ return strValue.includes(props.separator) ? strValue.split(props.separator) : [value]
188
+ }
189
+
190
+ /**
191
+ * 根据值查找对应列的索引
192
+ * @param values 值数组
193
+ * @returns 索引数组
194
+ */
195
+ const findColumnIndexs = (values: any[]): number[] => {
196
+ return values.map((item, columnIndex) => {
197
+ const column = props.columns[columnIndex]
198
+ if (!column) return 0
199
+
200
+ const index = column.findIndex((option) => {
201
+ const optionValue = typeof option === 'object' ? option[props.valueKey] : option
202
+ return optionValue === item
203
+ })
204
+ // 未找到时默认返回 0
205
+ return index < 0 ? 0 : index
206
+ })
207
+ }
208
+
177
209
  /**
178
210
  * 监听默认值,给索引赋值
179
211
  * */
180
212
  watch(
181
213
  () => props.modelValue,
182
- (v) =>
183
- setIndexs(
184
- (isArray(v)
185
- ? v
186
- : String(v).includes(props.separator)
187
- ? String(v).split(props.separator)
188
- : [v]
189
- )
190
- .map((item, i) =>
191
- props.columns[i]?.findIndex(
192
- (val) => (typeof val === 'object' ? val[props.valueKey] : val) === item
193
- )
194
- )
195
- .map((n) => (n < 0 ? 0 : n))
196
- ),
214
+ (value) => {
215
+ const values = parseModelValue(value)
216
+ const indexs = findColumnIndexs(values)
217
+ setIndexs(indexs)
218
+ },
197
219
  { immediate: true }
198
220
  )
199
221
 
@@ -212,49 +234,37 @@ watch(
212
234
  * 已选&&已确认的值显示在input上面的文案
213
235
  * */
214
236
  const inputLabelValue = computed((): string => {
215
- let firstItem = innerColumns.value[0][0]
216
- // //区分是不是对象数组
217
- if (firstItem && Object.prototype.toString.call(firstItem) === '[object Object]') {
218
- let res: Record<string, any>[] = []
219
- innerColumns.value.map((ite, i) => {
220
- res.push(
221
- ...innerColumns.value[i]?.filter((item) => {
222
- return isArray(props.modelValue)
223
- ? props.modelValue.includes(item[props.valueKey])
224
- : props.modelValue === item[props.valueKey]
225
- })
226
- )
227
- })
228
- res = res.map((item) => item[props.labelKey])
229
- return res.join(props.separator)
230
- } else {
231
- //用户确定的值,才显示到输入框
232
- if (props.modelValue.length && isArray(props.modelValue)) {
233
- return props.modelValue.join(props.separator)
234
- }
235
- return props.modelValue as string
237
+ const firstItem = innerColumns.value[0]?.[0]
238
+ if (!isObjectOption(firstItem)) {
239
+ // 非对象数组,直接返回值
240
+ return isArray(props.modelValue)
241
+ ? props.modelValue.join(props.separator)
242
+ : String(props.modelValue || '')
236
243
  }
244
+
245
+ // 对象数组,查找匹配项并返回label
246
+ const labels: string[] = []
247
+ const values = isArray(props.modelValue) ? props.modelValue : [props.modelValue]
248
+
249
+ innerColumns.value.forEach((column) => {
250
+ column?.forEach((item) => {
251
+ if (values.includes(getItemValue(item))) {
252
+ labels.push(getItemText(item))
253
+ }
254
+ })
255
+ })
256
+
257
+ return labels.join(props.separator)
237
258
  })
238
259
 
239
260
  /**
240
261
  * 已选,待确认的值
241
262
  * */
242
263
  const inputValue = computed(() => {
243
- let items = innerColumns.value.map((item, index) => item[innerIndex.value[index]])
244
- let res: any[] = []
245
- //区分是不是对象数组
246
- if (items[0] && Object.prototype.toString.call(items[0]) === '[object Object]') {
247
- //对象数组返回id集合
248
- items.forEach((element) => {
249
- res.push(element && element[props.valueKey])
250
- })
251
- } else {
252
- //非对象数组返回元素集合
253
- items.forEach((element) => {
254
- res.push(element)
255
- })
256
- }
257
- return res
264
+ return innerColumns.value.map((column, index) => {
265
+ const item = column[innerIndex.value[index]]
266
+ return getItemValue(item)
267
+ })
258
268
  })
259
269
 
260
270
  /**
@@ -266,15 +276,35 @@ const onShowByClickInput = () => {
266
276
  }
267
277
  }
268
278
 
279
+ /**
280
+ * 判断选项是否为对象类型
281
+ * */
282
+ const isObjectOption = (item: any): boolean => {
283
+ return item && Object.prototype.toString.call(item) === '[object Object]'
284
+ }
285
+
269
286
  /**
270
287
  * 获取item需要显示的文字,判别为对象还是文本
271
288
  * */
272
289
  const getItemText = (item: any) => {
273
- if (Object.prototype.toString.call(item) === '[object Object]' && props.labelKey) {
274
- return item[props.labelKey]
275
- } else {
276
- return item
290
+ return isObjectOption(item) && props.labelKey ? item[props.labelKey] : item
291
+ }
292
+
293
+ /**
294
+ * 获取选项的值
295
+ * */
296
+ const getItemValue = (item: any) => {
297
+ return isObjectOption(item) ? item[props.valueKey] : item
298
+ }
299
+
300
+ /**
301
+ * 关闭选择器的公共逻辑
302
+ * */
303
+ const closePicker = () => {
304
+ if (props.hasInput) {
305
+ showByClickInput.value = false
277
306
  }
307
+ emit('update:show', false)
278
308
  }
279
309
 
280
310
  /**
@@ -282,10 +312,7 @@ const getItemText = (item: any) => {
282
312
  * */
283
313
  const closeHandler = () => {
284
314
  if (props.closeOnClickOverlay) {
285
- if (props.hasInput) {
286
- showByClickInput.value = false
287
- }
288
- emit('update:show', false)
315
+ closePicker()
289
316
  emit('close')
290
317
  }
291
318
  }
@@ -294,10 +321,7 @@ const closeHandler = () => {
294
321
  * 点击工具栏的取消按钮
295
322
  * */
296
323
  const cancel = () => {
297
- if (props.hasInput) {
298
- showByClickInput.value = false
299
- }
300
- emit('update:show', false)
324
+ closePicker()
301
325
  emit('cancel')
302
326
  }
303
327
 
@@ -305,26 +329,18 @@ const cancel = () => {
305
329
  * 点击工具栏的确定按钮
306
330
  * */
307
331
  const onConfirm = () => {
308
- //如果用户还没有触发过change
332
+ // 如果用户还没有触发过change,使用默认索引
309
333
  if (!currentActiveValue.value.length) {
310
- let arr = [0]
311
- //如果有默认值&&默认值的数组长度是正确的,就用默认值
312
- if (
334
+ const defaultIndexs =
313
335
  Array.isArray(props.defaultIndex) &&
314
336
  props.defaultIndex.length === innerColumns.value.length
315
- ) {
316
- arr = [...props.defaultIndex]
317
- } else {
318
- //否则默认都选中第一个
319
- arr = Array(innerColumns.value.length).fill(0)
320
- }
321
- setIndexs(arr, true)
337
+ ? [...props.defaultIndex]
338
+ : Array(innerColumns.value.length).fill(0)
339
+ setIndexs(defaultIndexs, true)
322
340
  }
341
+
323
342
  emit('update:modelValue', inputValue.value)
324
- if (props.hasInput) {
325
- showByClickInput.value = false
326
- }
327
- emit('update:show', false)
343
+ closePicker()
328
344
  emit('confirm', {
329
345
  indexs: innerIndex.value,
330
346
  value: innerColumns.value.map((item, index) => item[innerIndex.value[index]]),
@@ -337,45 +353,29 @@ const onConfirm = () => {
337
353
  * */
338
354
  const changeHandler = (e: any) => {
339
355
  const { value } = e.detail
340
- // 优化:使用更高效的方式找出变化的列
341
- let changedColumnIndex = -1
342
- let changedItemIndex = 0
343
-
344
- // 优化循环:使用for...of循环更简洁,并且在找到变化后立即退出
345
- for (let [i, newValue] of value.entries()) {
346
- const oldValue = lastIndex.value[i] || 0
347
- if (newValue !== oldValue) {
348
- changedColumnIndex = i
349
- changedItemIndex = newValue
350
- currentActiveValue.value = value
351
- break
352
- }
356
+ // 找出变化的列
357
+ const changedIndex = value.findIndex((newValue, i) => newValue !== (lastIndex.value[i] ?? 0))
358
+
359
+ if (changedIndex === -1) return
360
+
361
+ currentActiveValue.value = value
362
+ columnIndex.value = changedIndex
363
+
364
+ const params = {
365
+ value: innerColumns.value.map((item, idx) => item[value[idx]]),
366
+ index: value[changedIndex],
367
+ indexs: value,
368
+ values: innerColumns.value,
369
+ columnIndex: changedIndex
353
370
  }
354
371
 
355
- // 如果有变化的列,才执行后续操作
356
- if (changedColumnIndex !== -1) {
357
- columnIndex.value = changedColumnIndex
358
-
359
- // 移除无条件重置索引的代码,仅在数据实际变化时重置
360
-
361
- // 优化:创建params对象时使用更简洁的方式
362
- const params = {
363
- value: innerColumns.value.map((item, idx) => item[value[idx]]),
364
- index: changedItemIndex,
365
- indexs: value,
366
- values: innerColumns.value,
367
- columnIndex: changedColumnIndex
368
- }
369
-
370
- // 将当前的各项变化索引,设置为"上一次"的索引变化值
371
- setIndexs(value, true)
372
-
373
- //如果是非自带输入框才会在change时候触发v-model绑值的变化
374
- if (!props.hasInput) {
375
- emit('update:modelValue', inputValue.value)
376
- }
377
- emit('change', params)
372
+ setIndexs(value, true)
373
+
374
+ // 如果是非自带输入框才会在change时候触发v-model绑值的变化
375
+ if (!props.hasInput) {
376
+ emit('update:modelValue', inputValue.value)
378
377
  }
378
+ emit('change', params)
379
379
  }
380
380
 
381
381
  /**
@@ -383,50 +383,27 @@ const changeHandler = (e: any) => {
383
383
  * */
384
384
  function setIndexs(index: number[], isSetLastIndex?: boolean) {
385
385
  innerIndex.value = index
386
- // 移除调试日志
387
386
  if (isSetLastIndex) {
388
- setLastIndex(index)
387
+ lastIndex.value = index
389
388
  }
390
389
  }
391
390
 
392
- /**
393
- * 记录上一次的各列索引位置
394
- * */
395
- const setLastIndex = (index: number[]) => {
396
- // 当能进入此方法,意味着当前设置的各列默认索引,即为“上一次”的选中值,需要记录,是因为changeHandler中
397
- // 需要拿前后的变化值进行对比,得出当前发生改变的是哪一列
398
- lastIndex.value = index
399
- }
400
-
401
391
  /**
402
392
  * 设置对应列选项的所有值
403
393
  * */
404
- const setColumnValues = (columnI: number, values: AnyObject[]) => {
394
+ const setColumnValues = (columnI: number, values: Array<string | PickerColumnVo>) => {
405
395
  innerColumns.value.splice(columnI, 1, values)
406
- let tmpIndex = deepClone(innerIndex.value)
407
- for (let i = 0; i < innerColumns.value.length; i++) {
408
- if (i > columnIndex.value) {
409
- tmpIndex[i] = 0
410
- }
411
- }
412
- // 一次性赋值,不能单个修改,否则无效
396
+ // 重置当前列之后的索引为0
397
+ const tmpIndex = innerIndex.value.map((_, i) =>
398
+ i > columnIndex.value ? 0 : innerIndex.value[i]
399
+ )
413
400
  setIndexs(tmpIndex, true)
414
401
  }
415
402
 
416
- /**
417
- * 获取对应列的所有选项
418
- * */
419
- const getColumnValues = (columnI: number) => {
420
- // 进行同步阻塞,因为外部得到change事件之后,可能需要执行setColumnValues更新列的值
421
- // 索引如果在外部change的回调中调用getColumnValues的话,可能无法得到变更后的列值,这里进行一定延时,保证值的准确性
422
- ;(async () => {
423
- await sleep()
424
- })()
425
- return innerColumns.value[columnI]
426
- }
427
-
428
- defineExpose({
429
- setColumnValues
403
+ defineExpose<IPickerExpose>({
404
+ setColumnValues,
405
+ onConfirm,
406
+ cancel
430
407
  })
431
408
  </script>
432
409
 
@@ -16,7 +16,10 @@ const pickerProps = {
16
16
  type: Boolean,
17
17
  default: false
18
18
  },
19
- /** 弹窗弹出模式 */
19
+ /**
20
+ * 弹窗弹出模式
21
+ * @values bottom, top
22
+ */
20
23
  popupMode: {
21
24
  type: String,
22
25
  default: 'bottom'
@@ -1,3 +1,8 @@
1
+ import type { ExtractPropTypes } from 'vue'
2
+ import type pickerProps from './props'
3
+
4
+ export interface HyPickerProps extends ExtractPropTypes<typeof pickerProps> {}
5
+
1
6
  export interface PickerColumnVo {
2
7
  /**
3
8
  * value必填,回填根据这个值判断
@@ -36,3 +41,20 @@ export interface IPickerEmits {
36
41
  /** 选中值触发 */
37
42
  (e: 'update:modelValue', value: any): void
38
43
  }
44
+
45
+ export interface IPickerExpose {
46
+ /**
47
+ * 设置某一列的值
48
+ * @param columnIndex 列索引,从0开始
49
+ * @param values 该列的选项数组
50
+ */
51
+ setColumnValues: (columnIndex: number, values: Array<string | PickerColumnVo>) => void
52
+ /**
53
+ * 手动触发确认选择
54
+ */
55
+ onConfirm: () => void
56
+ /**
57
+ * 关闭选择器弹窗
58
+ */
59
+ cancel: () => void
60
+ }
@@ -32,7 +32,7 @@ $z-index: 998;
32
32
  z-index: $z-index;
33
33
  position: relative;
34
34
  background-color: $hy-background--box;
35
- border-radius: $hy-border-radius-sm;
35
+ border-radius: $hy-radius-sm;
36
36
  }
37
37
 
38
38
  @include edeep(pos) {
@@ -43,8 +43,8 @@ $z-index: 998;
43
43
  min-height: 36px;
44
44
  z-index: $z-index;
45
45
  transition: opacity 0.2s;
46
- box-shadow: $hy-box-shadow;
47
- border-radius: $hy-border-radius-sm;
46
+ box-shadow: $hy-shadow-base;
47
+ border-radius: $hy-radius-sm;
48
48
  }
49
49
 
50
50
 
@@ -55,7 +55,7 @@ $z-index: 998;
55
55
 
56
56
  @include e(container) {
57
57
  position: relative;
58
- border-radius: $hy-border-radius-sm;
58
+ border-radius: $hy-radius-sm;
59
59
  }
60
60
 
61
61
  @include e(inner) {
@@ -64,7 +64,7 @@ $z-index: 998;
64
64
  line-height: 22px;
65
65
  z-index: $z-index;
66
66
  background-color: $hy-background--box;
67
- border-radius: $hy-border-radius-sm;
67
+ border-radius: $hy-radius-sm;
68
68
  box-sizing: content-box;
69
69
  width: 200px;
70
70
  }
@@ -79,5 +79,5 @@ $z-index: 998;
79
79
  z-index: $z-index;
80
80
  }
81
81
 
82
- @include squareArrow(6px, $hy-background--box, $z-index, $hy-box-shadow);
82
+ @include squareArrow(6px, $hy-background--box, $z-index, $hy-shadow-base);
83
83
  }
@@ -9,27 +9,28 @@
9
9
  background-color: $hy-background--container;
10
10
  position: relative;
11
11
  z-index: 9999;
12
+ overflow: hidden;
12
13
 
13
14
  @include m(round) {
14
15
 
15
16
  &-top {
16
- border-radius: 0 0 $hy-border-radius-lg $hy-border-radius-lg;
17
+ border-radius: 0 0 $hy-radius-lg $hy-radius-lg;
17
18
  }
18
19
 
19
20
  &-left {
20
- border-radius: 0 $hy-border-radius-lg $hy-border-radius-lg 0;
21
+ border-radius: 0 $hy-radius-lg $hy-radius-lg 0;
21
22
  }
22
23
 
23
24
  &-right {
24
- border-radius: $hy-border-radius-lg 0 0 $hy-border-radius-lg;
25
+ border-radius: $hy-radius-lg 0 0 $hy-radius-lg;
25
26
  }
26
27
 
27
28
  &-bottom {
28
- border-radius: $hy-border-radius-lg $hy-border-radius-lg 0 0;
29
+ border-radius: $hy-radius-lg $hy-radius-lg 0 0;
29
30
  }
30
31
 
31
32
  &-center {
32
- border-radius: $hy-border-radius-lg;
33
+ border-radius: $hy-radius-lg;
33
34
  }
34
35
  }
35
36
 
@@ -1,11 +1,11 @@
1
1
  <template>
2
2
  <text :class="['hy-price', customClass]" :style="priceStyle" @tap="handleClick">
3
3
  <text class="hy-price__prefix">{{ symbol }}</text>
4
- <text class="hy-price__text" :style="[{ 'font-size': addUnit(getPx(size) * ratio) }]">
5
- {{ priceOne?.[0] }}
4
+ <text class="hy-price__text" :style="integerStyle">
5
+ {{ priceData.integer }}
6
6
  </text>
7
7
  <text class="hy-price__decimal">
8
- {{ '.' + addZero(priceOne?.[1], num) }}
8
+ {{ priceData.decimal }}
9
9
  </text>
10
10
  </text>
11
11
  </template>
@@ -37,34 +37,63 @@ defineOptions({})
37
37
  const props = defineProps(priceProps)
38
38
  const emit = defineEmits<IPriceEmits>()
39
39
 
40
- // 价格整体样式
40
+ /**
41
+ * 格式化数字为千分位
42
+ */
43
+ const formatThousand = (value: string): string => {
44
+ return value.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
45
+ }
46
+
47
+ /**
48
+ * 处理价格数据
49
+ */
50
+ const priceData = computed(() => {
51
+ const text = props.text
52
+ if (text === undefined || text === null) {
53
+ error('text值不能为空')
54
+ return { integer: '0', decimal: '.00' }
55
+ }
56
+
57
+ const value = typeof text === 'string' ? text : String(text)
58
+ const hasDecimal = /\./g.test(value)
59
+
60
+ if (hasDecimal) {
61
+ const [integer, decimal] = value.split('.', 2)
62
+ return {
63
+ integer: formatThousand(integer),
64
+ decimal: '.' + addZero(decimal, props.num)
65
+ }
66
+ } else {
67
+ return {
68
+ integer: formatThousand(value),
69
+ decimal: '.' + addZero('', props.num)
70
+ }
71
+ }
72
+ })
73
+
74
+ /**
75
+ * 价格整体样式
76
+ */
41
77
  const priceStyle = computed<CSSProperties>(() => {
42
- const style: CSSProperties = {
78
+ const baseStyle: CSSProperties = {
43
79
  color: props.color,
44
80
  fontWeight: props.weight,
45
- fontStyle: props.slant ? 'oblique' : '',
46
81
  fontSize: addUnit(props.size)
47
82
  }
48
83
 
49
- return Object.assign(style, props.customStyle)
50
- })
51
-
52
- // 价格处理
53
- const priceOne = computed(() => {
54
- if (props.text === undefined || props.text === null) return error('text值不能为空')
55
-
56
- let value = typeof props.text === 'string' ? props.text : props.text.toString()
57
-
58
- // 格式化整数部分为千分位
59
- const formatValue = (val: string) => {
60
- return val.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
84
+ if (props.slant) {
85
+ baseStyle.fontStyle = 'oblique'
61
86
  }
62
87
 
63
- if (/\./g.test(value)) {
64
- const [integer, decimal] = value.split('.')
65
- return [formatValue(integer), decimal]
66
- } else {
67
- return [formatValue(value), '000000']
88
+ return { ...baseStyle, ...props.customStyle }
89
+ })
90
+
91
+ /**
92
+ * 整数部分样式
93
+ */
94
+ const integerStyle = computed<CSSProperties>(() => {
95
+ return {
96
+ fontSize: addUnit(getPx(props.size) * props.ratio)
68
97
  }
69
98
  })
70
99