@didaoktv/didaoui-uniapp 1.0.0 → 1.2.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 (114) hide show
  1. package/README.md +16 -7
  2. package/components/dd-action-sheet/dd-action-sheet.vue +3 -3
  3. package/components/dd-album/album.js +19 -0
  4. package/components/dd-album/dd-album.vue +345 -0
  5. package/components/dd-album/props.js +89 -0
  6. package/components/dd-avatar/avatar.js +19 -0
  7. package/components/dd-avatar/dd-avatar.vue +172 -160
  8. package/components/dd-avatar/props.js +84 -0
  9. package/components/dd-avatar-group/avatarGroup.js +14 -0
  10. package/components/dd-avatar-group/dd-avatar-group.vue +110 -0
  11. package/components/dd-avatar-group/props.js +57 -0
  12. package/components/dd-badge/dd-badge.vue +2 -2
  13. package/components/dd-barcode/dd-barcode.vue +1030 -0
  14. package/components/dd-bill-detail/dd-bill-detail.vue +265 -0
  15. package/components/dd-button/dd-button.vue +17 -17
  16. package/components/dd-calendar/dd-calendar.vue +357 -0
  17. package/components/dd-canvas/dd-canvas.vue +1088 -0
  18. package/components/dd-capsule-button/dd-capsule-button.vue +6 -6
  19. package/components/dd-car-keyboard/carKeyboard.js +6 -0
  20. package/components/dd-car-keyboard/dd-car-keyboard.vue +315 -0
  21. package/components/dd-car-keyboard/props.js +19 -0
  22. package/components/dd-cascader/dd-cascader.vue +405 -0
  23. package/components/dd-cell/dd-cell.vue +50 -23
  24. package/components/dd-cell-group/dd-cell-group.vue +32 -25
  25. package/components/dd-champion-card/dd-champion-card.vue +4 -4
  26. package/components/dd-checkbox/dd-checkbox.vue +30 -39
  27. package/components/dd-checkbox-group/dd-checkbox-group.vue +67 -0
  28. package/components/dd-copy/dd-copy.vue +74 -0
  29. package/components/dd-coupon/dd-coupon.vue +368 -0
  30. package/components/dd-cropper/dd-cropper.vue +1297 -0
  31. package/components/dd-dialog/dd-dialog.vue +1 -1
  32. package/components/dd-divider/dd-divider.vue +3 -3
  33. package/components/dd-dropdown-item/dd-dropdown-item.vue +5 -5
  34. package/components/dd-empty-state/dd-empty-state.vue +1 -1
  35. package/components/dd-field/dd-field.vue +531 -106
  36. package/components/dd-form/dd-form.vue +116 -0
  37. package/components/dd-form/rules.ts +84 -0
  38. package/components/dd-goods-sku/dd-goods-sku.vue +434 -0
  39. package/components/dd-icon/dd-icon.vue +2 -2
  40. package/components/dd-image/dd-image.vue +4 -4
  41. package/components/dd-input/dd-input.vue +5 -5
  42. package/components/dd-keyboard/dd-keyboard.vue +178 -0
  43. package/components/dd-keyboard/keyboard.js +22 -0
  44. package/components/dd-keyboard/props.js +89 -0
  45. package/components/dd-link/dd-link.vue +87 -0
  46. package/components/dd-link/link.js +18 -0
  47. package/components/dd-link/props.js +44 -0
  48. package/components/dd-list-cell/dd-list-cell.vue +4 -4
  49. package/components/dd-loading/dd-loading.vue +1 -1
  50. package/components/dd-loadmore/dd-loadmore.vue +2 -2
  51. package/components/dd-markdown/dd-markdown.vue +344 -0
  52. package/components/dd-markdown/marked.esm.mjs +7 -0
  53. package/components/dd-mini-program-navbar/dd-mini-program-navbar.vue +9 -9
  54. package/components/dd-navigation/dd-navigation.vue +5 -5
  55. package/components/dd-number-keyboard/dd-number-keyboard.vue +200 -0
  56. package/components/dd-number-keyboard/numberKeyboard.js +8 -0
  57. package/components/dd-number-keyboard/props.js +24 -0
  58. package/components/dd-parse/dd-parse.vue +534 -0
  59. package/components/dd-parse/node/handler.wxs +26 -0
  60. package/components/dd-parse/node/node.vue +603 -0
  61. package/components/dd-parse/parse.js +13 -0
  62. package/components/dd-parse/parser.js +1400 -0
  63. package/components/dd-parse/props.js +57 -0
  64. package/components/dd-popover/dd-popover.vue +10 -10
  65. package/components/dd-popover-item/dd-popover-item.vue +3 -3
  66. package/components/dd-popup/dd-popup.vue +5 -5
  67. package/components/dd-poster/dd-poster.vue +695 -0
  68. package/components/dd-progress/dd-progress.vue +3 -3
  69. package/components/dd-pull-refresh/dd-pull-refresh.vue +3 -3
  70. package/components/dd-qrcode/dd-qrcode.vue +509 -0
  71. package/components/dd-qrcode/qrcode.js +1283 -0
  72. package/components/dd-radio/dd-radio.vue +19 -20
  73. package/components/dd-radio-group/dd-radio-group.vue +53 -0
  74. package/components/dd-rate/dd-rate.vue +1 -1
  75. package/components/dd-room-card/dd-room-card.vue +3 -3
  76. package/components/dd-search-bar/dd-search-bar.vue +8 -8
  77. package/components/dd-segmented-tab/dd-segmented-tab.vue +6 -6
  78. package/components/dd-signature/dd-signature.vue +513 -0
  79. package/components/dd-skeleton/dd-skeleton.vue +1 -1
  80. package/components/dd-slider/dd-slider.vue +4 -4
  81. package/components/dd-stat-card/dd-stat-card.vue +5 -5
  82. package/components/dd-step/dd-step.vue +11 -11
  83. package/components/dd-stepper/dd-stepper.vue +6 -6
  84. package/components/dd-swipe-action/dd-swipe-action.vue +1 -1
  85. package/components/dd-swipeable-tab/dd-swipeable-tab.vue +1 -1
  86. package/components/dd-tabbar-item/dd-tabbar-item.vue +8 -8
  87. package/components/dd-tag/dd-tag.vue +17 -1
  88. package/components/dd-text/dd-text.vue +250 -0
  89. package/components/dd-text/props.js +120 -0
  90. package/components/dd-text/text.js +30 -0
  91. package/components/dd-text/value.js +87 -0
  92. package/components/dd-toast/dd-toast.vue +2 -2
  93. package/components/dd-upload/dd-upload.vue +4 -4
  94. package/components/dd-workorder-card/dd-workorder-card.vue +237 -0
  95. package/index.ts +50 -9
  96. package/libs/config/color.js +16 -0
  97. package/libs/config/config.js +25 -0
  98. package/libs/config/props.js +185 -0
  99. package/libs/config/zIndex.js +20 -0
  100. package/libs/function/digit.js +167 -0
  101. package/libs/function/index.js +932 -0
  102. package/libs/function/test.js +327 -0
  103. package/libs/i18n/index.d.ts +2 -0
  104. package/libs/i18n/index.js +89 -0
  105. package/libs/i18n/locales/zh-Hans.js +86 -0
  106. package/libs/mixin/button.js +18 -0
  107. package/libs/mixin/mixin.js +44 -0
  108. package/libs/mixin/mpMixin.js +13 -0
  109. package/libs/mixin/openType.js +27 -0
  110. package/libs/utils.ts +462 -0
  111. package/libs/vue.js +3 -0
  112. package/package.json +1 -1
  113. package/scss/_dd-shared.scss +40 -0
  114. package/scss/_variables.scss +4 -1
@@ -1,168 +1,180 @@
1
1
  <template>
2
- <view class="dd-avatar" :class="[`dd-avatar--${size}`, `dd-avatar--${shape}`, { 'dd-avatar--vip': vip }]">
3
- <view class="dd-avatar__inner">
4
- <image
5
- v-if="src && !fallback"
6
- class="dd-avatar__img"
7
- :src="src"
8
- mode="aspectFill"
9
- @error="onImgError"
10
- />
11
- <view v-else class="dd-avatar__text-wrap">
12
- <text class="dd-avatar__text">{{ displayText }}</text>
13
- </view>
14
- </view>
15
- <view v-if="online" class="dd-avatar__online"></view>
16
- </view>
2
+ <view
3
+ class="dd-avatar"
4
+ :class="[`dd-avatar--${shape}`]"
5
+ :style="[{
6
+ backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : random(0, 19)] : bgColor) : 'transparent',
7
+ width: addUnit(size),
8
+ height: addUnit(size),
9
+ }, addStyle(customStyle)]"
10
+ @tap="clickHandler"
11
+ >
12
+ <slot>
13
+ <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
14
+ <open-data
15
+ v-if="mpAvatar && allowMp"
16
+ type="userAvatarUrl"
17
+ :style="[{
18
+ width: addUnit(size),
19
+ height: addUnit(size)
20
+ }]"
21
+ />
22
+ <!-- #endif -->
23
+ <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
24
+ <template v-if="mpAvatar && allowMp"></template>
25
+ <!-- #endif -->
26
+ <dd-icon
27
+ v-else-if="icon"
28
+ :name="icon"
29
+ :size="fontSize"
30
+ :color="color"
31
+ ></dd-icon>
32
+ <dd-text
33
+ v-else-if="text"
34
+ :text="text"
35
+ :size="fontSize"
36
+ :color="color"
37
+ align="center"
38
+ customStyle="justify-content: center"
39
+ ></dd-text>
40
+ <image
41
+ class="dd-avatar__image"
42
+ v-else
43
+ :class="[`dd-avatar__image--${shape}`]"
44
+ :src="avatarUrl || defaultUrl"
45
+ :mode="mode"
46
+ @error="errorHandler"
47
+ :style="[{
48
+ width: addUnit(size),
49
+ height: addUnit(size)
50
+ }]"
51
+ ></image>
52
+ </slot>
53
+ </view>
17
54
  </template>
18
55
 
19
- <script setup lang="ts">
20
- import { computed, ref } from 'vue'
21
-
22
- interface Props {
23
- src?: string
24
- text?: string
25
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
26
- shape?: 'circle' | 'square'
27
- vip?: boolean
28
- online?: boolean
29
- }
30
-
31
- const props = withDefaults(defineProps<Props>(), {
32
- src: '',
33
- text: '',
34
- size: 'md',
35
- shape: 'circle',
36
- vip: false,
37
- online: false,
38
- })
39
-
40
- const fallback = ref(false)
41
-
42
- const displayText = computed(() => {
43
- const t = props.text || ''
44
- return t ? t.charAt(0).toUpperCase() : ''
45
- })
46
-
47
- function onImgError() {
48
- fallback.value = true
49
- }
56
+ <script>
57
+ import { props } from './props';
58
+ import { mpMixin } from '../../libs/mixin/mpMixin';
59
+ import { mixin } from '../../libs/mixin/mixin';
60
+ import { addStyle, addUnit, random } from '../../libs/function/index';
61
+ const base64Avatar =
62
+ "data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYG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";
63
+ /**
64
+ * Avatar 头像
65
+ * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
66
+ *
67
+ * @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
68
+ * @property {String} shape 头像形状 ( circle (默认) | square)
69
+ * @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
70
+ * @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill'
71
+ * @property {String} text 用文字替代图片,级别优先于src
72
+ * @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc'
73
+ * @property {String} color 文字颜色 (默认 '#ffffff' )
74
+ * @property {String | Number} fontSize 文字大小 (默认 18 )
75
+ * @property {String} icon 显示的图标
76
+ * @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
77
+ * @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false
78
+ * @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
79
+ * @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
80
+ * @property {String} name 组件标识符 (默认 'level'
81
+ * @property {Object} customStyle 定义需要用到的外部样式
82
+ *
83
+ * @event {Function} click 点击组件时触发 index: 用户传递的标识符
84
+ * @example <dd-avatar :src="src" mode="square"></dd-avatar>
85
+ */
86
+ export default {
87
+ name: 'dd-avatar',
88
+ mixins: [mpMixin, mixin, props],
89
+ data() {
90
+ return {
91
+ // 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
92
+ colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
93
+ '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
94
+ '#73d1f1',
95
+ '#80a7dc'
96
+ ],
97
+ avatarUrl: this.src,
98
+ allowMp: false
99
+ }
100
+ },
101
+ watch: {
102
+ // 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
103
+ // 而组件内部不能直接修改props的值,所以需要一个中间变量
104
+ src: {
105
+ immediate: true,
106
+ handler(newVal) {
107
+ this.avatarUrl = newVal
108
+ // 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
109
+ if(!newVal) {
110
+ this.errorHandler()
111
+ }
112
+ }
113
+ }
114
+ },
115
+ computed: {
116
+ imageStyle() {
117
+ const style = {}
118
+ return style
119
+ }
120
+ },
121
+ created() {
122
+ this.init()
123
+ },
124
+ emits: ["click"],
125
+ methods: {
126
+ addStyle,
127
+ addUnit,
128
+ random,
129
+ init() {
130
+ // 目前只有这几个小程序平台具有open-data标签
131
+ // 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
132
+ // 故目前自动获取小程序头像只支持这几个平台
133
+ // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
134
+ this.allowMp = true
135
+ // #endif
136
+ },
137
+ // 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
138
+ isImg() {
139
+ return this.src.indexOf('/') !== -1
140
+ },
141
+ // 图片加载时失败时触发
142
+ errorHandler() {
143
+ this.avatarUrl = this.defaultUrl || base64Avatar
144
+ },
145
+ clickHandler(e) {
146
+ this.$emit('click', this.name, e)
147
+ }
148
+ }
149
+ }
50
150
  </script>
51
151
 
52
152
  <style lang="scss" scoped>
53
153
  @import '../../scss/variables';
54
- @import '../../scss/mixins';
55
-
56
- .dd-avatar {
57
- position: relative;
58
- display: inline-flex;
59
- flex-shrink: 0;
60
-
61
- &__inner {
62
- width: 100%;
63
- height: 100%;
64
- overflow: hidden;
65
- display: flex;
66
- align-items: center;
67
- justify-content: center;
68
- box-sizing: border-box;
69
- background: $dd-gradient-primary;
70
- }
71
-
72
- &__img {
73
- width: 100%;
74
- height: 100%;
75
- }
76
-
77
- &__text-wrap {
78
- display: flex;
79
- align-items: center;
80
- justify-content: center;
81
- width: 100%;
82
- height: 100%;
83
- }
84
-
85
- &__text {
86
- font-family: $dd-font-heading;
87
- font-weight: 600;
88
- color: $dd-color-white;
89
- line-height: 1;
90
- }
91
-
92
- &__online {
93
- position: absolute;
94
- right: 0;
95
- bottom: 0;
96
- width: 25%;
97
- height: 25%;
98
- min-width: 16rpx;
99
- min-height: 16rpx;
100
- max-width: 28rpx;
101
- max-height: 28rpx;
102
- border-radius: 50%;
103
- background: $dd-success-500;
104
- border: 4rpx solid $dd-bg-elevated;
105
- box-shadow: 0 0 12rpx rgba(76, 175, 80, 0.6);
106
- box-sizing: border-box;
107
- }
108
- }
109
-
110
- // === 形状 ===
111
- .dd-avatar--circle .dd-avatar__inner {
112
- border-radius: 50%;
113
- }
114
-
115
- .dd-avatar--square .dd-avatar__inner {
116
- border-radius: $dd-radius-md;
117
- }
118
-
119
- // === 5 尺寸 (px→rpx x2) ===
120
- .dd-avatar--xs {
121
- width: 48rpx;
122
- height: 48rpx;
123
- .dd-avatar__text { font-size: $dd-font-size-caption; }
124
- }
125
-
126
- .dd-avatar--sm {
127
- width: 64rpx;
128
- height: 64rpx;
129
- .dd-avatar__text { font-size: $dd-font-size-body; }
130
- }
131
-
132
- .dd-avatar--md {
133
- width: 88rpx;
134
- height: 88rpx;
135
- .dd-avatar__text { font-size: $dd-font-size-h3; }
136
- }
137
-
138
- .dd-avatar--lg {
139
- width: 128rpx;
140
- height: 128rpx;
141
- .dd-avatar__text { font-size: $dd-font-size-h2; }
142
- }
143
-
144
- .dd-avatar--xl {
145
- width: 192rpx;
146
- height: 192rpx;
147
- .dd-avatar__text { font-size: $dd-font-size-h1; }
148
- }
149
-
150
- // === VIP: 金色渐变环 + 发光 ===
151
- .dd-avatar--vip {
152
- padding: 4rpx;
153
- background: $dd-gradient-primary-wide;
154
- box-shadow: $dd-shadow-glow-gold-lg;
155
-
156
- .dd-avatar__inner {
157
- border-radius: inherit;
158
- }
159
- }
160
-
161
- .dd-avatar--vip.dd-avatar--circle {
162
- border-radius: 50%;
163
- }
164
-
165
- .dd-avatar--vip.dd-avatar--square {
166
- border-radius: $dd-radius-lg;
167
- }
154
+ @import '../../scss/dd-shared';
155
+
156
+ .dd-avatar {
157
+ @include flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+
161
+ &--circle {
162
+ border-radius: $dd-radius-full;
163
+ }
164
+
165
+ &--square {
166
+ border-radius: 4px;
167
+ }
168
+
169
+ &__image {
170
+ &--circle {
171
+ border-radius: $dd-radius-full;
172
+ overflow: hidden;
173
+ }
174
+
175
+ &--square {
176
+ border-radius: 4px;
177
+ }
178
+ }
179
+ }
168
180
  </style>
@@ -0,0 +1,84 @@
1
+ import { defineMixin } from '../../libs/vue'
2
+ import AvatarDefaultProps from './avatar'
3
+ import { registerComponentProps } from '../../libs/config/props.js'
4
+
5
+ const defProps = registerComponentProps(AvatarDefaultProps)
6
+ import test from '../../libs/function/test';
7
+ export const props = defineMixin({
8
+ props: {
9
+ // 头像图片路径(不能为相对路径)
10
+ src: {
11
+ type: String,
12
+ default: () => defProps.avatar.src
13
+ },
14
+ // 头像形状,circle-圆形,square-方形
15
+ shape: {
16
+ type: String,
17
+ default: () => defProps.avatar.shape
18
+ },
19
+ // 头像尺寸
20
+ size: {
21
+ type: [String, Number],
22
+ default: () => defProps.avatar.size
23
+ },
24
+ // 裁剪模式
25
+ mode: {
26
+ type: String,
27
+ default: () => defProps.avatar.mode
28
+ },
29
+ // 显示的文字
30
+ text: {
31
+ type: String,
32
+ default: () => defProps.avatar.text
33
+ },
34
+ // 背景色
35
+ bgColor: {
36
+ type: String,
37
+ default: () => defProps.avatar.bgColor
38
+ },
39
+ // 文字颜色
40
+ color: {
41
+ type: String,
42
+ default: () => defProps.avatar.color
43
+ },
44
+ // 文字大小
45
+ fontSize: {
46
+ type: [String, Number],
47
+ default: () => defProps.avatar.fontSize
48
+ },
49
+ // 显示的图标
50
+ icon: {
51
+ type: String,
52
+ default: () => defProps.avatar.icon
53
+ },
54
+ // 显示小程序头像,只对百度,微信,QQ小程序有效
55
+ mpAvatar: {
56
+ type: Boolean,
57
+ default: () => defProps.avatar.mpAvatar
58
+ },
59
+ // 是否使用随机背景色
60
+ randomBgColor: {
61
+ type: Boolean,
62
+ default: () => defProps.avatar.randomBgColor
63
+ },
64
+ // 加载失败的默认头像(组件有内置默认图片)
65
+ defaultUrl: {
66
+ type: String,
67
+ default: () => defProps.avatar.defaultUrl
68
+ },
69
+ // 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
70
+ colorIndex: {
71
+ type: [String, Number],
72
+ // 校验参数规则,索引在0-19之间
73
+ validator(n) {
74
+ return test.range(n, [0, 19]) || n === ''
75
+ },
76
+ default: () => defProps.avatar.colorIndex
77
+ },
78
+ // 组件标识符
79
+ name: {
80
+ type: String,
81
+ default: () => defProps.avatar.name
82
+ }
83
+ }
84
+ })
@@ -0,0 +1,14 @@
1
+ export default {
2
+ // avatarGroup 组件
3
+ avatarGroup: {
4
+ urls: [],
5
+ maxCount: 5,
6
+ shape: 'circle',
7
+ mode: 'scaleToFill',
8
+ showMore: true,
9
+ size: 40,
10
+ keyName: '',
11
+ gap: 0.5,
12
+ extraValue: 0
13
+ }
14
+ }
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <view class="dd-avatar-group">
3
+ <view
4
+ class="dd-avatar-group__item"
5
+ v-for="(item, index) in showUrl"
6
+ :key="index"
7
+ :style="{
8
+ marginLeft: index === 0 ? 0 : addUnit(-size * gap)
9
+ }"
10
+ >
11
+ <dd-avatar
12
+ :size="size"
13
+ :shape="shape"
14
+ :mode="mode"
15
+ :src="testObject(item) ? keyName && item[keyName] || item.url : item"
16
+ ></dd-avatar>
17
+ <view
18
+ class="dd-avatar-group__item__show-more"
19
+ v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
20
+ @tap="clickHandler"
21
+ >
22
+ <dd-text
23
+ color="#ffffff"
24
+ :size="size * 0.4"
25
+ :text="`+${extraValue || urls.length - showUrl.length}`"
26
+ align="center"
27
+ customStyle="justify-content: center"
28
+ ></dd-text>
29
+ </view>
30
+ </view>
31
+ </view>
32
+ </template>
33
+
34
+ <script>
35
+ import { props } from './props';
36
+ import { mpMixin } from '../../libs/mixin/mpMixin';
37
+ import { mixin } from '../../libs/mixin/mixin';
38
+ import { addUnit } from '../../libs/function/index';
39
+ import test from '../../libs/function/test';
40
+ /**
41
+ * AvatarGroup 头像组
42
+ * @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
43
+ *
44
+ * @property {Array} urls 头像图片组 (默认 [] )
45
+ * @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
46
+ * @property {String} shape 头像形状( 'circle' (默认) | 'square' )
47
+ * @property {String} mode 图片裁剪模式(默认 'scaleToFill' )
48
+ * @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
49
+ * @property {String | Number} size 头像大小 (默认 40 )
50
+ * @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
51
+ * @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 )
52
+ * @property {String | Number} extraValue 需额外显示的值
53
+ * @event {Function} showMore 头像组更多点击
54
+ * @example <dd-avatar-group:urls="urls" size="35" gap="0.4" ></dd-avatar-group:urls=>
55
+ */
56
+ export default {
57
+ name: 'dd-avatar-group',
58
+ mixins: [mpMixin, mixin, props],
59
+ data() {
60
+ return {
61
+
62
+ }
63
+ },
64
+ computed: {
65
+ showUrl() {
66
+ return this.urls.slice(0, this.maxCount)
67
+ }
68
+ },
69
+ emits: ["showMore"],
70
+ methods: {
71
+ addUnit,
72
+ testObject: test.object,
73
+ clickHandler() {
74
+ this.$emit('showMore')
75
+ }
76
+ },
77
+ }
78
+ </script>
79
+
80
+ <style lang="scss" scoped>
81
+ @import '../../scss/variables';
82
+ @import '../../scss/dd-shared';
83
+
84
+ .dd-avatar-group {
85
+ @include flex;
86
+
87
+ &__item {
88
+ margin-left: -10px;
89
+ position: relative;
90
+
91
+ &--no-indent {
92
+ // 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
93
+ margin-left: 0;
94
+ }
95
+
96
+ &__show-more {
97
+ position: absolute;
98
+ top: 0;
99
+ bottom: 0;
100
+ left: 0;
101
+ right: 0;
102
+ background-color: rgba(0, 0, 0, 0.3);
103
+ @include flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ border-radius: 100px;
107
+ }
108
+ }
109
+ }
110
+ </style>
@@ -0,0 +1,57 @@
1
+ import { defineMixin } from '../../libs/vue'
2
+ import AvatarGroupDefaultProps from './avatarGroup'
3
+ import { registerComponentProps } from '../../libs/config/props.js'
4
+
5
+ const defProps = registerComponentProps(AvatarGroupDefaultProps)
6
+ export const props = defineMixin({
7
+ props: {
8
+ // 头像图片组
9
+ urls: {
10
+ type: Array,
11
+ default: () => defProps.avatarGroup.urls
12
+ },
13
+ // 最多展示的头像数量
14
+ maxCount: {
15
+ type: [String, Number],
16
+ default: () => defProps.avatarGroup.maxCount
17
+ },
18
+ // 头像形状
19
+ shape: {
20
+ type: String,
21
+ default: () => defProps.avatarGroup.shape
22
+ },
23
+ // 图片裁剪模式
24
+ mode: {
25
+ type: String,
26
+ default: () => defProps.avatarGroup.mode
27
+ },
28
+ // 超出maxCount时是否显示查看更多的提示
29
+ showMore: {
30
+ type: Boolean,
31
+ default: () => defProps.avatarGroup.showMore
32
+ },
33
+ // 头像大小
34
+ size: {
35
+ type: [String, Number],
36
+ default: () => defProps.avatarGroup.size
37
+ },
38
+ // 指定从数组的对象元素中读取哪个属性作为图片地址
39
+ keyName: {
40
+ type: String,
41
+ default: () => defProps.avatarGroup.keyName
42
+ },
43
+ // 头像之间的遮挡比例
44
+ gap: {
45
+ type: [String, Number],
46
+ validator(value) {
47
+ return value >= 0 && value <= 1
48
+ },
49
+ default: () => defProps.avatarGroup.gap
50
+ },
51
+ // 需额外显示的值
52
+ extraValue: {
53
+ type: [Number, String],
54
+ default: () => defProps.avatarGroup.extraValue
55
+ }
56
+ }
57
+ })
@@ -84,7 +84,7 @@ const visible = computed(() => {
84
84
  &__num {
85
85
  font-family: $dd-font-mono;
86
86
  font-weight: 600;
87
- color: #ffffff;
87
+ color: $dd-color-white;
88
88
  line-height: 1;
89
89
  padding: 0 10rpx;
90
90
  }
@@ -118,7 +118,7 @@ const visible = computed(() => {
118
118
  .dd-badge__sup--text {
119
119
  height: 36rpx;
120
120
  border-radius: $dd-radius-full;
121
- font-size: 20rpx;
121
+ font-size: $dd-font-size-caption;
122
122
  }
123
123
 
124
124
  // === 4 色变体 ===