瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

201 lines
4.1 KiB

<template>
<view class="avatar-stack" v-if="avatars && avatars.length > 0">
<view class="avatar-container">
<!-- 显示的头像列表 -->
<view
class="avatar-item"
v-for="(avatar, index) in displayAvatars"
:key="index"
:style="{
width: avatarSize + 'rpx',
height: avatarSize + 'rpx',
marginLeft: index > 0 ? (-overlapOffset + 'rpx') : '0',
zIndex: displayAvatars.length - index
}"
@click="handleAvatarClick(avatar, index)"
>
<image
:src="avatar.userHead || '/static/image/center/default-avatar.png'"
mode="aspectFill"
class="avatar-image"
/>
</view>
<!-- 更多数量显示 -->
<view
class="more-count"
v-if="remainingCount > 0"
:style="{
width: avatarSize + 'rpx',
height: avatarSize + 'rpx',
marginLeft: displayAvatars.length > 0 ? (-overlapOffset + 'rpx') : '0',
zIndex: 1
}"
@click="handleMoreClick"
>
<text class="count-text">+{{ remainingCount }}</text>
</view>
</view>
<!-- 描述文本 -->
<!-- <view class="description" v-if="showDescription">
<text class="desc-text">{{ getDescriptionText() }}</text>
</view> -->
</view>
</template>
<script>
export default {
name: 'AvatarStack',
props: {
// 头像数据数组
avatars: {
type: Array,
default: () => []
},
// 最大显示数量
maxDisplay: {
type: Number,
default: 5
},
// 头像大小
avatarSize: {
type: Number,
default: 60 // rpx
},
// 重叠偏移量
overlapOffset: {
type: Number,
default: 15 // rpx
},
// 是否显示描述文本
showDescription: {
type: Boolean,
default: true
},
// 描述文本类型
descriptionType: {
type: String,
default: 'viewed' // viewed, liked, shared
},
// 自定义描述文本
customDescription: {
type: String,
default: ''
}
},
computed: {
// 显示的头像列表
displayAvatars() {
return this.avatars.slice(0, this.maxDisplay)
},
// 剩余数量
remainingCount() {
return Math.max(0, this.avatars.length - this.maxDisplay)
}
},
methods: {
// 获取描述文本
getDescriptionText() {
if (this.customDescription) {
return this.customDescription
}
const total = this.avatars.length
if (total === 0) return ''
switch (this.descriptionType) {
case 'viewed':
return `${total}人看过`
case 'liked':
return `${total}人点赞`
case 'shared':
return `${total}人分享`
default:
return `${total}人参与`
}
},
// 头像点击事件
handleAvatarClick(avatar, index) {
this.$emit('avatarClick', { avatar, index })
},
// 更多按钮点击事件
handleMoreClick() {
this.$emit('moreClick', {
total: this.avatars.length,
remaining: this.remainingCount
})
}
}
}
</script>
<style scoped lang="scss">
.avatar-stack {
display: flex;
flex-direction: column;
align-items: flex-start;
.avatar-container {
display: flex;
align-items: center;
.avatar-item {
position: relative;
border-radius: 50%;
overflow: hidden;
background-color: #fff;
border: 4rpx solid #fff;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
transition: transform 0.2s ease;
&:hover {
transform: scale(1.1);
}
.avatar-image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.more-count {
position: relative;
border-radius: 50%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
border: 4rpx solid #fff;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.count-text {
color: #fff;
font-size: 20rpx;
font-weight: 600;
}
}
}
.description {
margin-top: 15rpx;
.desc-text {
font-size: 24rpx;
color: #666;
line-height: 1.4;
}
}
}
// 不同尺寸适配
@media screen and (max-width: 750rpx) {
.avatar-stack .description .desc-text {
font-size: 22rpx;
}
}
</style>