| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <template>
- <view class="nana-avatar-stack">
- <template
- v-for="(img, i) of urls"
- :key="i"
- >
- <Avatar v-if="i === 0"
- :innerStyle="{
- ...imageStyle,
- marginLeft: 0,
- zIndex: 0,
- }"
- :url="urls[i]"
- :size="size"
- @click="handleClick(i)"
- />
- <Avatar v-else-if="i < maxCount"
- :innerStyle="{
- ...imageStyle,
- zIndex: i,
- }"
- :url="urls[i]"
- :size="size"
- @click="handleClick(i)"
- />
- <view v-else-if="showOverflowCount && i === maxCount"
- :style="{
- ...imageStyle,
- ...themeStyles.overflowCount.value,
- zIndex: maxCount,
- }"
- @click="handleClick(i)"
- >
- <text :style="themeStyles.overflowCountText.value">+{{urls.length - i}}</text>
- </view>
- </template>
- </view>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue';
- import { propGetThemeVar, useTheme, type ViewStyle } from '../theme/ThemeDefine';
- import Avatar from './Avatar.vue';
- import { DynamicColor, DynamicVar } from '../theme/ThemeTools';
- export interface AvatarStackProp {
- /**
- * 默认头像
- */
- defaultAvatar?: string,
- /**
- * 头像的图标URL
- */
- urls: string[],
- /**
- * 最大显示多少个头像,超过后显示数字
- * @default 5
- */
- maxCount?: number,
- /**
- * 超过最大显示后是否显示数字
- * @default true
- */
- showOverflowCount?: boolean,
- /**
- * 设置头像之间的距离
- * @default size / 3
- */
- imageMargin?: number,
- /**
- * 头像的大小
- * @default 70
- */
- size?: number,
- /**
- * 头像是否是圆形的
- * @default true
- */
- round?: boolean,
- /**
- * 头像是圆角的大小,仅在 round=false 时有效
- * @default 50%
- */
- radius?: number|string,
- /**
- * 是否为头像添加边框
- * @default false
- */
- border?: boolean,
- /**
- * 头像边框宽度
- * @default 1.5
- */
- borderWidth?: number,
- /**
- * 头像边框颜色
- * @default Color.white
- */
- borderColor?: string,
- /**
- * 超出显示文字背景样式
- */
- overflowCountStyle?: ViewStyle,
- /**
- * 超出显示文字自定义样式
- */
- overflowCountTextStyle?: ViewStyle,
- /**
- * 是否可以点击放大预览
- * @default false
- */
- preview?: boolean,
- }
- const emit = defineEmits([ 'click' ]);
- const themeContext = useTheme();
- const props = withDefaults(defineProps<AvatarStackProp>(), {
- defaultAvatar: '',
- urls: () => [],
- maxCount: () => propGetThemeVar('AvatarStackMaxCount', 5),
- showOverflowCount: () => propGetThemeVar('AvatarStackShowOverflowCount', true),
- imageMargin: 0,
- size: () => propGetThemeVar('AvatarStackSize', 70),
- round: () => propGetThemeVar('AvatarStackRound', true),
- radius: () => propGetThemeVar('AvatarStackRadius', '50%'),
- border: () => propGetThemeVar('AvatarStackBorder', false),
- borderWidth: () => propGetThemeVar('AvatarStackBorderWidth', 10),
- borderColor: () => propGetThemeVar('AvatarStackBorderColor', 'white'),
- });
- const imageStyle = computed(() => {
- const size = themeContext.resolveThemeSize(props.size, 0);
- return {
- marginLeft: props.imageMargin ? themeContext.resolveThemeSize(props.imageMargin) : `calc(-${size} / 3)`,
- borderRadius: props.round ? '50%' : themeContext.resolveThemeSize(props.radius),
- border: props.border ? `${themeContext.resolveThemeSize(props.borderWidth)} solid ${themeContext.resolveThemeColor(props.borderColor)}` : undefined,
- width: size,
- height: size,
- }
- });
- const themeStyles = themeContext.useThemeStyles({
- overflowCount: {
- backgroundColor: DynamicColor('AvatarStackOverflowCountBackgroundColor', 'white'),
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- display: 'flex',
- },
- overflowCountText: {
- fontSize: DynamicVar('AvatarStackOverflowCountTextFontSize', 12),
- color: DynamicColor('AvatarStackOverflowCountTextColor', 'text.content'),
- },
- })
- function handleClick(i: number) {
- if (props.preview) {
- uni.previewImage({
- urls: props.urls,
- current: i,
- })
- }
- emit('click', i);
- }
- </script>
- <style>
- .nana-avatar-stack {
- display: flex;
- flex-direction: row;
- align-items: center;
- }
- </style>
|