uview-pro 0.5.0 → 0.5.2

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 (52) hide show
  1. package/changelog.md +68 -24
  2. package/components/u-action-sheet/types.ts +1 -1
  3. package/components/u-alert-tips/u-alert-tips.vue +15 -15
  4. package/components/u-calendar/types.ts +3 -3
  5. package/components/u-calendar/u-calendar.vue +11 -11
  6. package/components/u-checkbox/types.ts +5 -1
  7. package/components/u-checkbox/u-checkbox.vue +41 -18
  8. package/components/u-checkbox-group/types.ts +2 -0
  9. package/components/u-checkbox-group/u-checkbox-group.vue +56 -15
  10. package/components/u-count-down/u-count-down.vue +4 -4
  11. package/components/u-empty/u-empty.vue +14 -14
  12. package/components/u-field/u-field.vue +18 -2
  13. package/components/u-form/u-form.vue +1 -1
  14. package/components/u-form-item/u-form-item.vue +12 -5
  15. package/components/u-full-screen/u-full-screen.vue +2 -2
  16. package/components/u-gap/u-gap.vue +3 -3
  17. package/components/u-input/types.ts +1 -1
  18. package/components/u-keyboard/types.ts +2 -2
  19. package/components/u-keyboard/u-keyboard.vue +3 -3
  20. package/components/u-link/types.ts +1 -1
  21. package/components/u-loadmore/types.ts +3 -3
  22. package/components/u-modal/types.ts +4 -4
  23. package/components/u-navbar/u-navbar.vue +8 -2
  24. package/components/u-no-network/types.ts +1 -1
  25. package/components/u-no-network/u-no-network.vue +5 -5
  26. package/components/u-pagination/types.ts +2 -2
  27. package/components/u-picker/types.ts +2 -2
  28. package/components/u-radio/types.ts +2 -0
  29. package/components/u-radio/u-radio.vue +16 -7
  30. package/components/u-radio-group/u-radio-group.vue +1 -1
  31. package/components/u-read-more/types.ts +2 -2
  32. package/components/u-search/types.ts +5 -3
  33. package/components/u-search/u-search.vue +1 -0
  34. package/components/u-section/types.ts +1 -1
  35. package/components/u-select/types.ts +2 -2
  36. package/components/u-tabbar/u-tabbar.vue +1 -1
  37. package/components/u-text/u-text.vue +7 -2
  38. package/components/u-toast/u-toast.vue +14 -11
  39. package/components/u-transition/types.ts +35 -0
  40. package/components/u-transition/u-transition.vue +437 -0
  41. package/components/u-upload/types.ts +1 -1
  42. package/components/u-upload/u-upload.vue +12 -12
  43. package/components/u-verification-code/types.ts +3 -3
  44. package/index.ts +2 -0
  45. package/libs/hooks/index.ts +2 -0
  46. package/libs/hooks/useDebounce.ts +15 -0
  47. package/libs/hooks/useThrottle.ts +16 -0
  48. package/locale/lang/en-US.ts +19 -19
  49. package/locale/lang/zh-CN.ts +19 -19
  50. package/package.json +9 -9
  51. package/types/components.d.ts +1 -0
  52. package/types/global.d.ts +14 -0
package/changelog.md CHANGED
@@ -1,27 +1,71 @@
1
- ## 0.5.0(2026-01-14
2
-
3
- ### ✨ Features | 新功能
4
-
5
- - **locale:** 添加组件国际化支持和 use locale hooks ([ff96211](https://github.com/anyup/uView-Pro/commit/ff96211423d27bde350a2ea4b9f1d5a5eb72d604))
6
- - **locale:** 添加中、英文国际化语言字段支持 ([257eb41](https://github.com/anyup/uView-Pro/commit/257eb4143ac39cab4940ab76844d0c3be02b198c))
7
- - **locale:** 所有组件实现组件国际化显示替换 ([ef52ff7](https://github.com/anyup/uView-Pro/commit/ef52ff7669c8cb7389377b8bdd4da681dddbb0a6))
8
- - **locale:** 跟随vue-i18n国际化语言切换功能 ([cccecb0](https://github.com/anyup/uView-Pro/commit/cccecb03763990689e6e66d856cf3588157a61b6))
9
- - **fullScreen:** 优化fullscreen页面配置和实现,支持国际化 ([8518218](https://github.com/anyup/uView-Pro/commit/85182186848fa6443ed74de9af1e3f5cd15fa724))
10
- - **locale:** 新增locale国际化和vue-i18n切换示例页面 ([da79723](https://github.com/anyup/uView-Pro/commit/da797230005ff130ea66c315921e4d8d9fa613c1))
11
- - **demo-page:** 添加支付宝小程序navbar兼容性处理 ([75284a4](https://github.com/anyup/uView-Pro/commit/75284a403b9eb7dee9625279ca5cadd14bba3a63))
12
- - **u-skeleton:** 重构u-skeleton骨架屏组件实现全新设计 ([c39405d](https://github.com/anyup/uView-Pro/commit/c39405dfd8c4e1fe06fd842efde79ebf6706b0d1))
13
- - **u-tabbar:** 重构u-tabbar组件内部结构,增加图标文字间距配置 ([e5655da](https://github.com/anyup/uView-Pro/commit/e5655da55c515a8288b12e37084dfec093da542b))
14
- - **mp-weixin:** 添加小程序全局分享功能 ([e4f8bf5](https://github.com/anyup/uView-Pro/commit/e4f8bf5baae237e8dc443de7c90cd751ef045101))
15
- - **useLocale:** uselocale hooks 支持命名空间功能 ([4d6e8f2](https://github.com/anyup/uView-Pro/commit/4d6e8f26976725cfdf862bd21af3648b864fdc29))
16
- - **u-tabbar:** 优化u-tabbar文本样式渲染优先级 ([7d73861](https://github.com/anyup/uView-Pro/commit/7d73861b4cbe1266bc4cbfff31b45a57d9ed960f))
17
- - **locale:** 初始化多语言时添加 isForce 参数支持强制设置默认语言 ([3309017](https://github.com/anyup/uView-Pro/commit/3309017e6fea3bc00f10efcec9f3ec3f83de9a88))
18
- - **demo:** 优化国际化配置示例并添加多语言支持 ([177b978](https://github.com/anyup/uView-Pro/commit/177b97869f14023daf4bca632093076716b616d6))
19
- - **theme:** 主题配置支持强制初始化功能 ([95c895d](https://github.com/anyup/uView-Pro/commit/95c895d0cfb1df37aa6285b88a2247f83add7361))
20
-
21
- ### 👥 Contributors
22
-
23
- <a href="https://github.com/anyup"><img src="https://github.com/anyup.png?size=40" width="40" height="40" alt="anyup" title="anyup"/></a>
24
-
1
+ ## 0.5.2(2026-01-23
2
+
3
+ ### ✨ Features | 新功能
4
+
5
+ - **u-checkbox-group:** 重构u-checkbox多选框组件,group支持v-model双向绑定,标准化使用api ([e4a12f1](https://github.com/anyup/uView-Pro/commit/e4a12f1af6a4d8cae18823b42a918052df36b62d))
6
+ - **hooks:** 新增防抖和节流hook ([4b09373](https://github.com/anyup/uView-Pro/commit/4b09373c31dc3ab7ded01c6ea0cfdf902642b857))
7
+ - **u-search:** 新增adjust-position属性控制键盘弹出时的高度调节 ([3443e7c](https://github.com/anyup/uView-Pro/commit/3443e7cc0d754c10df03134e8bc2c6c977758610))
8
+ - **u-tabbar:** 调整u-tabbar凸起图标上边距以优化显示效果 ([d0963be](https://github.com/anyup/uView-Pro/commit/d0963be197079733779719aae43694ae5b47e6bc))
9
+ - **u-transition:** 新增transition过渡动画组件 ([28ee2c8](https://github.com/anyup/uView-Pro/commit/28ee2c8b0f74bae722f0fe50e498e3407907d2f6))
10
+ - **u-transition:** 添加动画模式切换时的时序控制 ([af4bf0a](https://github.com/anyup/uView-Pro/commit/af4bf0a690128ba16e7660d2ae54c5b93644cfdf))
11
+ - **u-text:** 优化按钮模式在block模式下的样式 ([afda81d](https://github.com/anyup/uView-Pro/commit/afda81d0c8fa7b628b81f8368e6bd2983779b7c9))
12
+ - **u-radio:** 添加label和value属性支持 ([1b824d7](https://github.com/anyup/uView-Pro/commit/1b824d7867dc7fcc3793d7b5d84cbbbcb512dab0))
13
+
14
+ ### 🐛 Bug Fixes | Bug 修复
15
+
16
+ - **u-checkbox-group:** 修复全选时,u-checkbox-group多次触发change的问题 ([9f813df](https://github.com/anyup/uView-Pro/commit/9f813dfb8a2b8e178b7347223281e09b039f74b0))
17
+ - **u-gap:** 修复 gap 间隔槽传递带单位尺寸无法正确解析的问题 ([cc24efd](https://github.com/anyup/uView-Pro/commit/cc24efd658e510fb9655a189ceaee2647db81528))
18
+ - **u-alert-tips:** 修复微信小程序下组件样式和图标配置不生效的问题 ([d74900e](https://github.com/anyup/uView-Pro/commit/d74900e9e8a61a68b8971abc81e440e8449d3576))
19
+ - **u-navbar:** 修复获取状态栏高度在某些平台失败的问题 ([b8b288e](https://github.com/anyup/uView-Pro/commit/b8b288e33348b78e03be349c6c123e36511342af))
20
+ - **u-toast:** 修复toast提示组件设置prop无效的问题 ([ecd3a0a](https://github.com/anyup/uView-Pro/commit/ecd3a0a23a0ca039fa0abe3a946bfdf1024dd10a))
21
+ - **locale:** 修复注册uview-pro组件库时,未传递locale导致初始化语言包失败的问题 ([d716100](https://github.com/anyup/uView-Pro/commit/d7161000fe9e3d222453603d8fa31d29a1b9a9bb))
22
+ - **u-field:** 修复u-field在禁用状态下,点击输入框无法触发click事件的问题 ([f47761d](https://github.com/anyup/uView-Pro/commit/f47761d00fe2913f0e611577651a3f4108e060b6))
23
+
24
+ ### ♻️ Code Refactoring | 代码重构
25
+
26
+ - **demo:** 重构u-checkbox复选框演示示例 ([77fc19b](https://github.com/anyup/uView-Pro/commit/77fc19b6f23f8d776b7a56ef9ac27726da7405a1))
27
+ - **demo:** 同步鸿蒙应用功能 ([2ac7050](https://github.com/anyup/uView-Pro/commit/2ac70500004e04bd22442d696e3e869ba33ac355))
28
+ - update release scripts ([818f8b9](https://github.com/anyup/uView-Pro/commit/818f8b9cf6a0a22893305f76e4af2b71409cbc12))
29
+
30
+ ### 👥 Contributors
31
+
32
+ <a href="https://github.com/anyup"><img src="https://github.com/anyup.png?size=40" width="40" height="40" alt="anyup" title="anyup"/></a>
33
+
34
+ ## 0.5.1(2026-01-15)
35
+
36
+ ### ✨ Features | 新功能
37
+
38
+ - **locale:** 统一组件国际化命名空间,以保持命名的一致性并避免与自定义字段时冲突 ([8bd3cc3](https://github.com/anyup/uView-Pro/commit/8bd3cc32b26349da63f5005cb3c29e575c831142))
39
+ - **u-form:** 支持label插槽功能 ([f82994f](https://github.com/anyup/uView-Pro/commit/f82994f5500ec4509dff64c05e115afb0465d4a2))
40
+
41
+ ### 👥 Contributors
42
+
43
+ <a href="https://github.com/anyup"><img src="https://github.com/anyup.png?size=40" width="40" height="40" alt="anyup" title="anyup"/></a>
44
+
45
+ ## 0.5.0(2026-01-14)
46
+
47
+ ### ✨ Features | 新功能
48
+
49
+ - **locale:** 添加组件国际化支持和 use locale hooks ([ff96211](https://github.com/anyup/uView-Pro/commit/ff96211423d27bde350a2ea4b9f1d5a5eb72d604))
50
+ - **locale:** 添加中、英文国际化语言字段支持 ([257eb41](https://github.com/anyup/uView-Pro/commit/257eb4143ac39cab4940ab76844d0c3be02b198c))
51
+ - **locale:** 所有组件实现组件国际化显示替换 ([ef52ff7](https://github.com/anyup/uView-Pro/commit/ef52ff7669c8cb7389377b8bdd4da681dddbb0a6))
52
+ - **locale:** 跟随vue-i18n国际化语言切换功能 ([cccecb0](https://github.com/anyup/uView-Pro/commit/cccecb03763990689e6e66d856cf3588157a61b6))
53
+ - **fullScreen:** 优化fullscreen页面配置和实现,支持国际化 ([8518218](https://github.com/anyup/uView-Pro/commit/85182186848fa6443ed74de9af1e3f5cd15fa724))
54
+ - **locale:** 新增locale国际化和vue-i18n切换示例页面 ([da79723](https://github.com/anyup/uView-Pro/commit/da797230005ff130ea66c315921e4d8d9fa613c1))
55
+ - **demo-page:** 添加支付宝小程序navbar兼容性处理 ([75284a4](https://github.com/anyup/uView-Pro/commit/75284a403b9eb7dee9625279ca5cadd14bba3a63))
56
+ - **u-skeleton:** 重构u-skeleton骨架屏组件实现全新设计 ([c39405d](https://github.com/anyup/uView-Pro/commit/c39405dfd8c4e1fe06fd842efde79ebf6706b0d1))
57
+ - **u-tabbar:** 重构u-tabbar组件内部结构,增加图标文字间距配置 ([e5655da](https://github.com/anyup/uView-Pro/commit/e5655da55c515a8288b12e37084dfec093da542b))
58
+ - **mp-weixin:** 添加小程序全局分享功能 ([e4f8bf5](https://github.com/anyup/uView-Pro/commit/e4f8bf5baae237e8dc443de7c90cd751ef045101))
59
+ - **useLocale:** uselocale hooks 支持命名空间功能 ([4d6e8f2](https://github.com/anyup/uView-Pro/commit/4d6e8f26976725cfdf862bd21af3648b864fdc29))
60
+ - **u-tabbar:** 优化u-tabbar文本样式渲染优先级 ([7d73861](https://github.com/anyup/uView-Pro/commit/7d73861b4cbe1266bc4cbfff31b45a57d9ed960f))
61
+ - **locale:** 初始化多语言时添加 isForce 参数支持强制设置默认语言 ([3309017](https://github.com/anyup/uView-Pro/commit/3309017e6fea3bc00f10efcec9f3ec3f83de9a88))
62
+ - **demo:** 优化国际化配置示例并添加多语言支持 ([177b978](https://github.com/anyup/uView-Pro/commit/177b97869f14023daf4bca632093076716b616d6))
63
+ - **theme:** 主题配置支持强制初始化功能 ([95c895d](https://github.com/anyup/uView-Pro/commit/95c895d0cfb1df37aa6285b88a2247f83add7361))
64
+
65
+ ### 👥 Contributors
66
+
67
+ <a href="https://github.com/anyup"><img src="https://github.com/anyup.png?size=40" width="40" height="40" alt="anyup" title="anyup"/></a>
68
+
25
69
  ## 0.4.13(2026-01-06)
26
70
 
27
71
  ### ✨ Features | 新功能
@@ -34,7 +34,7 @@ export const ActionSheetProps = {
34
34
  /** 弹出的z-index值 */
35
35
  zIndex: { type: [String, Number], default: 0 },
36
36
  /** 取消按钮的文字提示 */
37
- cancelText: { type: String, default: () => t('actionSheet.cancelText') },
37
+ cancelText: { type: String, default: () => t('uActionSheet.cancelText') },
38
38
  /** 字体颜色 */
39
39
  color: { type: String, default: () => getColor('mainColor') },
40
40
  /** 字体大小 */
@@ -23,9 +23,9 @@
23
23
  v-if="showIcon"
24
24
  :name="uIconName"
25
25
  :size="description ? 40 : 32"
26
- class="u-icon"
27
26
  :color="uIconType"
28
27
  :custom-style="iconStyle"
28
+ custom-class="u-tips-icon"
29
29
  ></u-icon>
30
30
  </view>
31
31
  <view class="u-alert-content" @tap.stop="onClick">
@@ -44,10 +44,10 @@
44
44
  name="close"
45
45
  color="var(--u-light-color)"
46
46
  :size="22"
47
- class="u-close-icon"
48
- :style="{
47
+ :custom-style="{
49
48
  top: description ? '18rpx' : '24rpx'
50
49
  }"
50
+ custom-class="u-close-icon"
51
51
  ></u-icon>
52
52
  </view>
53
53
  <text
@@ -56,8 +56,9 @@
56
56
  :style="{
57
57
  top: description ? '18rpx' : '24rpx'
58
58
  }"
59
- >{{ closeText }}</text
60
59
  >
60
+ {{ closeText }}
61
+ </text>
61
62
  </view>
62
63
  </template>
63
64
 
@@ -75,7 +76,6 @@ export default {
75
76
  </script>
76
77
 
77
78
  <script setup lang="ts">
78
- import uIcon from '../u-icon/u-icon.vue';
79
79
  import { computed } from 'vue';
80
80
  import { $u } from '../..';
81
81
  import { AlertTipsProps } from './types';
@@ -195,6 +195,16 @@ function onClose() {
195
195
  &--border--info-disabled {
196
196
  border-color: $u-type-info-disabled;
197
197
  }
198
+
199
+ :deep(.u-tips-icon) {
200
+ margin-right: 16rpx;
201
+ }
202
+
203
+ :deep(.u-close-icon) {
204
+ position: absolute;
205
+ right: 20rpx;
206
+ cursor: pointer;
207
+ }
198
208
  }
199
209
 
200
210
  .u-close-alert-tips {
@@ -202,10 +212,6 @@ function onClose() {
202
212
  visibility: hidden;
203
213
  }
204
214
 
205
- .u-icon {
206
- margin-right: 16rpx;
207
- }
208
-
209
215
  .u-alert-title {
210
216
  font-size: 28rpx;
211
217
  color: $u-main-color;
@@ -217,12 +223,6 @@ function onClose() {
217
223
  color: $u-content-color;
218
224
  }
219
225
 
220
- .u-close-icon {
221
- position: absolute;
222
- top: 20rpx;
223
- right: 20rpx;
224
- }
225
-
226
226
  .u-close-hover {
227
227
  color: red;
228
228
  }
@@ -50,9 +50,9 @@ export const CalendarProps = {
50
50
  /** 范围内日期字体颜色 */
51
51
  rangeColor: { type: String, default: () => getColor('primary') },
52
52
  /** mode=range时生效,起始日期自定义文案 */
53
- startText: { type: String, default: () => t('calendar.startText') },
53
+ startText: { type: String, default: () => t('uCalendar.startText') },
54
54
  /** mode=range时生效,结束日期自定义文案 */
55
- endText: { type: String, default: () => t('calendar.endText') },
55
+ endText: { type: String, default: () => t('uCalendar.endText') },
56
56
  /** 按钮样式类型 */
57
57
  btnType: { type: String as PropType<ThemeType>, default: 'primary' },
58
58
  /** 当前选中日期带选中效果 */
@@ -62,7 +62,7 @@ export const CalendarProps = {
62
62
  /** 是否显示右上角的关闭图标 */
63
63
  closeable: { type: Boolean, default: true },
64
64
  /** 顶部的提示文字 */
65
- toolTip: { type: String, default: () => t('calendar.toolTip') },
65
+ toolTip: { type: String, default: () => t('uCalendar.toolTip') },
66
66
  /** 是否显示农历 */
67
67
  showLunar: { type: Boolean, default: false },
68
68
  /** 是否在页面中显示 */
@@ -223,11 +223,11 @@
223
223
  <view class="u-calendar__bottom">
224
224
  <view class="u-calendar__bottom__choose">
225
225
  <text>{{ mode == 'date' ? activeDate : startDate }}</text>
226
- <text v-if="endDate">{{ t('calendar.to') }}{{ endDate }}</text>
226
+ <text v-if="endDate">{{ t('uCalendar.to') }}{{ endDate }}</text>
227
227
  </view>
228
228
  <view class="u-calendar__bottom__btn">
229
229
  <u-button :type="btnType" shape="circle" size="default" @click="btnFix(false)">
230
- {{ t('calendar.confirmText') }}
230
+ {{ t('uCalendar.confirmText') }}
231
231
  </u-button>
232
232
  </view>
233
233
  </view>
@@ -317,13 +317,13 @@ const isStart = ref(true);
317
317
  const min = ref<{ year: number; month: number; day: number } | null>(null);
318
318
  const max = ref<{ year: number; month: number; day: number } | null>(null);
319
319
  const weekDayZh = ref([
320
- t('calendar.sun'),
321
- t('calendar.mon'),
322
- t('calendar.tue'),
323
- t('calendar.wed'),
324
- t('calendar.thu'),
325
- t('calendar.fri'),
326
- t('calendar.sat')
320
+ t('uCalendar.sun'),
321
+ t('uCalendar.mon'),
322
+ t('uCalendar.tue'),
323
+ t('uCalendar.wed'),
324
+ t('uCalendar.thu'),
325
+ t('uCalendar.fri'),
326
+ t('uCalendar.sat')
327
327
  ]);
328
328
 
329
329
  const dataChange = computed(() => `${props.mode}-${props.minDate}-${props.maxDate}`);
@@ -455,7 +455,7 @@ function getWeekday(yearNum: number, monthNum: number) {
455
455
  function checkRange(yearNum: number) {
456
456
  let overstep = false;
457
457
  if (yearNum < Number(props.minYear) || yearNum > Number(props.maxYear)) {
458
- uni.showToast({ title: t('calendar.outOfRange'), icon: 'none' });
458
+ uni.showToast({ title: t('uCalendar.outOfRange'), icon: 'none' });
459
459
  overstep = true;
460
460
  }
461
461
  return overstep;
@@ -503,7 +503,7 @@ function changeData() {
503
503
  daysArr.value = generateArray(1, days.value);
504
504
  weekday.value = getWeekday(year.value, month.value);
505
505
  weekdayArr.value = generateArray(1, weekday.value);
506
- showTitle.value = `${year.value}${t('calendar.year')}${month.value}${t('calendar.month')}`;
506
+ showTitle.value = `${year.value}${t('uCalendar.year')}${month.value}${t('uCalendar.month')}`;
507
507
  if (props.showLunar) {
508
508
  lunarArr.value = [];
509
509
  daysArr.value.forEach(d => {
@@ -10,8 +10,12 @@ export type CheckboxValue = string | number | boolean;
10
10
 
11
11
  export const CheckboxProps = {
12
12
  ...baseProps,
13
- /** checkbox的名称 */
13
+ /** checkbox的标签 */
14
+ label: { type: String, default: '' },
15
+ /** checkbox的值 */
14
16
  name: { type: [String, Number], default: '' },
17
+ /** checkbox的值,不传递时为name的属性 */
18
+ value: { type: [String, Number], default: '' },
15
19
  /** 形状,square为方形,circle为原型 */
16
20
  shape: { type: String as PropType<Shape>, default: '' },
17
21
  /** 是否为选中状态 */
@@ -15,7 +15,9 @@
15
15
  fontSize: $u.addUnit(labelSize)
16
16
  }"
17
17
  >
18
- <slot />
18
+ <slot>
19
+ {{ label }}
20
+ </slot>
19
21
  </view>
20
22
  </view>
21
23
  </template>
@@ -34,7 +36,7 @@ export default {
34
36
  </script>
35
37
 
36
38
  <script setup lang="ts">
37
- import { computed } from 'vue';
39
+ import { computed, ref, watch } from 'vue';
38
40
  import { $u, useChildren } from '../..';
39
41
  import { CheckboxProps } from './types';
40
42
 
@@ -55,6 +57,29 @@ import { CheckboxProps } from './types';
55
57
 
56
58
  const props = defineProps(CheckboxProps);
57
59
  const emit = defineEmits(['change', 'update:modelValue']);
60
+ // checkbox 是否选中,true/false
61
+ const checkedValue = ref(props.modelValue);
62
+
63
+ // checkbox 的value值,id
64
+ const checkboxValue = computed(() => {
65
+ if (props.value !== '') return props.value;
66
+ return props.name;
67
+ });
68
+
69
+ watch(
70
+ () => props.modelValue,
71
+ (newVal: boolean) => {
72
+ checkedValue.value = newVal;
73
+ }
74
+ );
75
+
76
+ watch(
77
+ () => checkedValue.value,
78
+ (newVal: boolean) => {
79
+ emit('update:modelValue', newVal);
80
+ },
81
+ { immediate: true }
82
+ );
58
83
 
59
84
  // 使用子组件Hook
60
85
  const { parentExposed } = useChildren('u-checkbox', 'u-checkbox-group');
@@ -92,7 +117,7 @@ const elShape = computed(() => {
92
117
  // 图标样式
93
118
  const iconStyle = computed(() => {
94
119
  let style: Record<string, string> = {};
95
- if (elActiveColor.value && props.modelValue && !isDisabled.value) {
120
+ if (elActiveColor.value && checkedValue.value && !isDisabled.value) {
96
121
  style.borderColor = elActiveColor.value;
97
122
  style.backgroundColor = elActiveColor.value;
98
123
  }
@@ -103,15 +128,15 @@ const iconStyle = computed(() => {
103
128
 
104
129
  // checkbox内部的勾选图标,如果选中状态,为白色,否则为透明色即可
105
130
  const iconColor = computed(() => {
106
- return props.modelValue ? 'var(--u-white-color)' : 'transparent';
131
+ return checkedValue.value ? 'var(--u-white-color)' : 'transparent';
107
132
  });
108
133
 
109
134
  const iconClass = computed(() => {
110
135
  let classes: string[] = [];
111
136
  classes.push('u-checkbox__icon-wrap--' + elShape.value);
112
- if (props.modelValue == true) classes.push('u-checkbox__icon-wrap--checked');
137
+ if (checkedValue.value == true) classes.push('u-checkbox__icon-wrap--checked');
113
138
  if (isDisabled.value) classes.push('u-checkbox__icon-wrap--disabled');
114
- if (props.modelValue && isDisabled.value) classes.push('u-checkbox__icon-wrap--disabled--checked');
139
+ if (checkedValue.value && isDisabled.value) classes.push('u-checkbox__icon-wrap--disabled--checked');
115
140
  return classes.join(' ');
116
141
  });
117
142
 
@@ -157,12 +182,7 @@ function toggle() {
157
182
  * 触发change事件
158
183
  */
159
184
  function emitEvent() {
160
- const changeValue = {
161
- value: !props.modelValue,
162
- name: props.name
163
- };
164
- emit('change', changeValue);
165
-
185
+ emit('change', !checkedValue.value);
166
186
  // 通知父组件状态变化
167
187
  setTimeout(() => {
168
188
  if (parentExposed.value?.emitEvent) {
@@ -176,31 +196,34 @@ function emitEvent() {
176
196
  */
177
197
  function setValue() {
178
198
  // 判断是否超过了可选的最大数量
179
- if (props.modelValue == true) {
199
+ if (checkedValue.value == true) {
180
200
  emitEvent();
181
- emit('update:modelValue', false);
201
+ checkedValue.value = false;
182
202
  } else {
183
203
  if (parentExposed?.value?.validateSelection && !parentExposed?.value?.validateSelection()) {
184
204
  return;
185
205
  }
186
206
  emitEvent();
187
- emit('update:modelValue', true);
207
+ checkedValue.value = true;
188
208
  }
189
209
  }
190
210
 
191
211
  // 设置组件的modelValue值
192
212
  function setChecked(data: any) {
193
213
  if (!isDisabled.value) {
194
- emit('update:modelValue', data.checked);
195
- if (data.checked !== props.modelValue) {
214
+ const needEmit = checkedValue.value !== data.checked;
215
+ checkedValue.value = data.checked;
216
+ if (needEmit) {
196
217
  emitEvent();
197
218
  }
198
219
  }
199
220
  }
200
221
 
201
222
  defineExpose({
202
- isChecked: computed(() => props.modelValue),
223
+ isChecked: computed(() => checkedValue.value),
224
+ label: props.label,
203
225
  name: props.name,
226
+ value: checkboxValue.value,
204
227
  setValue,
205
228
  emitEvent,
206
229
  props,
@@ -10,6 +10,8 @@ import { getColor } from '../../';
10
10
 
11
11
  export const CheckboxGroupProps = {
12
12
  ...baseProps,
13
+ /** 绑定值,选中的复选框name组成的数组 */
14
+ modelValue: { type: Array as PropType<(string | number)[]>, default: undefined },
13
15
  /** 最多能选中多少个checkbox */
14
16
  max: { type: Number, default: 999 },
15
17
  /** 是否禁用所有复选框 */
@@ -18,14 +18,15 @@ export default {
18
18
  </script>
19
19
 
20
20
  <script setup lang="ts">
21
- import { getCurrentInstance, computed } from 'vue';
22
- import { $u, useParent, useChildren } from '../..';
21
+ import { getCurrentInstance, computed, watch, nextTick, onMounted } from 'vue';
22
+ import { $u, useParent, useChildren, useDebounce } from '../..';
23
23
  import { CheckboxGroupProps } from './types';
24
24
 
25
25
  /**
26
26
  * checkboxGroup 开关选择器父组件Group
27
27
  * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
28
28
  * @tutorial https://uviewpro.cn/zh/components/checkbox.html
29
+ * @property {Array} modelValue 绑定值,选中的复选框name组成的数组(支持v-model双向绑定)
29
30
  * @property {String Number} max 最多能选中多少个checkbox(默认999)
30
31
  * @property {String Number} size 组件整体的大小,单位rpx(默认40)
31
32
  * @property {Boolean} disabled 是否禁用所有checkbox(默认false)
@@ -35,32 +36,65 @@ import { CheckboxGroupProps } from './types';
35
36
  * @property {String} shape 外观形状,shape-方形,circle-圆形(默认circle)
36
37
  * @property {Boolean} wrap 是否每个checkbox都换行(默认false)
37
38
  * @property {String} active-color 选中时的颜色,应用到所有子Checkbox组件(默认主题色primary)
38
- * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
39
- * @example <u-checkbox-group></u-checkbox-group>
39
+ * @event {Function} change 任一个checkbox状态发生变化时触发,回调为选中的name数组
40
+ * @example <u-checkbox-group v-model="selectedValues">
41
+ * <u-checkbox name="apple">苹果</u-checkbox>
42
+ * <u-checkbox name="banana">香蕉</u-checkbox>
43
+ * </u-checkbox-group>
40
44
  */
41
- const instance = getCurrentInstance();
42
45
  const props = defineProps(CheckboxGroupProps);
43
46
  const emit = defineEmits(['update:modelValue', 'change']);
44
47
 
45
48
  // 使用父组件Hook
46
49
  const { children, broadcast } = useParent('u-checkbox-group');
47
50
  const { emitToParent } = useChildren('u-checkbox-group', 'u-form-item');
51
+ const { debounce } = useDebounce(1);
48
52
 
49
53
  /**
50
- * 派发 change 事件和表单校验
54
+ * 根据modelValue设置子组件状态
51
55
  */
52
- function emitEvent() {
53
- // 收集所有选中的 name
54
- let values: any[] = [];
56
+ function syncChildrenSelection() {
57
+ if (!children || children.length === 0 || !props.modelValue) return;
58
+ const modelValueSet = new Set(props.modelValue);
55
59
  children.forEach((child: any) => {
56
- if (child.getExposed?.()?.isChecked.value) {
57
- values.push(child.getExposed?.()?.name);
60
+ const childValue = child.getExposed?.()?.value;
61
+ const shouldBeChecked = modelValueSet.has(childValue);
62
+ const isCurrentlyChecked = child.getExposed?.()?.isChecked.value;
63
+
64
+ if (shouldBeChecked !== isCurrentlyChecked) {
65
+ child.getExposed?.()?.setChecked({ checked: shouldBeChecked });
58
66
  }
59
67
  });
60
- emit('change', values);
61
- setTimeout(() => {
62
- emitToParent('onFormChange', values);
63
- }, 60);
68
+ }
69
+
70
+ /**
71
+ * 监听modelValue变化,同步子组件状态
72
+ */
73
+ watch(
74
+ () => props.modelValue,
75
+ () => {
76
+ syncChildrenSelection();
77
+ }
78
+ );
79
+
80
+ /**
81
+ * 派发 change 事件和表单校验
82
+ */
83
+ function emitEvent() {
84
+ debounce(() => {
85
+ // 收集所有选中的 name
86
+ let values: any[] = [];
87
+ children.forEach((child: any) => {
88
+ if (child.getExposed?.()?.isChecked.value) {
89
+ values.push(child.getExposed?.()?.value);
90
+ }
91
+ });
92
+ emit('change', values);
93
+ emit('update:modelValue', values);
94
+ setTimeout(() => {
95
+ emitToParent('onFormChange', values);
96
+ }, 60);
97
+ });
64
98
  }
65
99
 
66
100
  /**
@@ -96,6 +130,12 @@ function validateSelection() {
96
130
  return true;
97
131
  }
98
132
 
133
+ onMounted(() => {
134
+ nextTick(() => {
135
+ syncChildrenSelection();
136
+ });
137
+ });
138
+
99
139
  // 使用defineExpose暴露给外部
100
140
  defineExpose({
101
141
  // props
@@ -106,6 +146,7 @@ defineExpose({
106
146
  setAllChecked,
107
147
  getSelectedValues,
108
148
  validateSelection,
149
+ syncChildrenSelection,
109
150
 
110
151
  // 计算属性
111
152
  selectedCount: computed(() => children.filter(child => child.getExposed?.()?.isChecked.value).length),
@@ -18,7 +18,7 @@
18
18
  }"
19
19
  v-if="props.showDays && (props.hideZeroDay || (!props.hideZeroDay && d != '00'))"
20
20
  >
21
- {{ props.separator == 'colon' && props.showHours ? ':' : t('countDown.day') }}
21
+ {{ props.separator == 'colon' && props.showHours ? ':' : t('uCountDown.day') }}
22
22
  </view>
23
23
  <view class="u-countdown-item" :style="$u.toStyle(itemStyle)" v-if="props.showHours">
24
24
  <view class="u-countdown-time" :style="{ fontSize: props.fontSize + 'rpx', color: props.color }">
@@ -34,7 +34,7 @@
34
34
  }"
35
35
  v-if="props.showHours"
36
36
  >
37
- {{ props.separator == 'colon' && props.showMinutes ? ':' : t('countDown.hour') }}
37
+ {{ props.separator == 'colon' && props.showMinutes ? ':' : t('uCountDown.hour') }}
38
38
  </view>
39
39
  <view class="u-countdown-item" :style="$u.toStyle(itemStyle)" v-if="props.showMinutes">
40
40
  <view class="u-countdown-time" :style="{ fontSize: props.fontSize + 'rpx', color: props.color }">
@@ -50,7 +50,7 @@
50
50
  }"
51
51
  v-if="props.showMinutes"
52
52
  >
53
- {{ props.separator == 'colon' && props.showSeconds ? ':' : t('countDown.minute') }}
53
+ {{ props.separator == 'colon' && props.showSeconds ? ':' : t('uCountDown.minute') }}
54
54
  </view>
55
55
  <view class="u-countdown-item" :style="$u.toStyle(itemStyle)" v-if="props.showSeconds">
56
56
  <view class="u-countdown-time" :style="{ fontSize: props.fontSize + 'rpx', color: props.color }">
@@ -62,7 +62,7 @@
62
62
  :style="{ fontSize: props.separatorSize + 'rpx', color: props.separatorColor, paddingBottom: 0 }"
63
63
  v-if="props.showSeconds && props.separator == 'zh'"
64
64
  >
65
- {{ t('countDown.second') }}
65
+ {{ t('uCountDown.second') }}
66
66
  </view>
67
67
  </view>
68
68
  </template>
@@ -66,20 +66,20 @@ const props = defineProps(EmptyProps);
66
66
  */
67
67
  const icons = computed(() => {
68
68
  return {
69
- car: t('empty.car'),
70
- page: t('empty.page'),
71
- search: t('empty.search'),
72
- address: t('empty.address'),
73
- wifi: t('empty.wifi'),
74
- order: t('empty.order'),
75
- coupon: t('empty.coupon'),
76
- favor: t('empty.favor'),
77
- permission: t('empty.permission'),
78
- history: t('empty.history'),
79
- news: t('empty.news'),
80
- message: t('empty.message'),
81
- list: t('empty.list'),
82
- data: t('empty.data')
69
+ car: t('uEmpty.car'),
70
+ page: t('uEmpty.page'),
71
+ search: t('uEmpty.search'),
72
+ address: t('uEmpty.address'),
73
+ wifi: t('uEmpty.wifi'),
74
+ order: t('uEmpty.order'),
75
+ coupon: t('uEmpty.coupon'),
76
+ favor: t('uEmpty.favor'),
77
+ permission: t('uEmpty.permission'),
78
+ history: t('uEmpty.history'),
79
+ news: t('uEmpty.news'),
80
+ message: t('uEmpty.message'),
81
+ list: t('uEmpty.list'),
82
+ data: t('uEmpty.data')
83
83
  };
84
84
  });
85
85
  </script>
@@ -31,7 +31,7 @@
31
31
  </text>
32
32
  </view>
33
33
  <view class="fild-body">
34
- <view class="u-flex-1 u-flex" :style="[inputWrapStyle]">
34
+ <view class="u-flex-1 u-flex u-field-input-wrap" :style="[inputWrapStyle]">
35
35
  <textarea
36
36
  v-if="props.type === 'textarea'"
37
37
  class="u-flex-1 u-textarea-class"
@@ -69,10 +69,12 @@
69
69
  @confirm="onConfirm"
70
70
  @tap="fieldClick"
71
71
  />
72
+ <!-- 透明遮罩,只在disabled时显示,用于响应点击事件 -->
73
+ <view v-if="props.disabled" class="u-field-disabled-overlay" @tap="fieldClick"></view>
72
74
  </view>
73
75
  <u-icon
76
+ v-if="props.clearable && props.modelValue != '' && focused && !props.disabled"
74
77
  :size="props.clearSize"
75
- v-if="props.clearable && props.modelValue != '' && focused"
76
78
  name="close-circle-fill"
77
79
  color="var(--u-light-color)"
78
80
  class="u-clear-icon"
@@ -385,4 +387,18 @@ function fieldClick() {
385
387
  .u-button-wrap {
386
388
  margin-left: 8rpx;
387
389
  }
390
+
391
+ .u-field-input-wrap {
392
+ position: relative;
393
+ }
394
+
395
+ .u-field-disabled-overlay {
396
+ position: absolute;
397
+ top: 0;
398
+ left: 0;
399
+ right: 0;
400
+ bottom: 0;
401
+ background-color: transparent;
402
+ z-index: 1;
403
+ }
388
404
  </style>