116 lines
2.1 KiB
Vue
116 lines
2.1 KiB
Vue
<template>
|
|
<div
|
|
class="safe-avatar"
|
|
:style="{
|
|
width: size + 'px',
|
|
height: size + 'px'
|
|
}"
|
|
>
|
|
<img
|
|
v-if="!imageError && src"
|
|
:src="src"
|
|
:alt="alt"
|
|
@error="handleImageError"
|
|
@load="handleImageLoad"
|
|
/>
|
|
<div v-else class="avatar-placeholder">
|
|
<span class="avatar-text">{{ avatarText }}</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed } from 'vue'
|
|
|
|
interface Props {
|
|
src?: string
|
|
alt?: string
|
|
size?: number
|
|
name?: string
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
src: '',
|
|
alt: '头像',
|
|
size: 32,
|
|
name: '用户'
|
|
})
|
|
|
|
const imageError = ref(false)
|
|
|
|
// 根据用户名生成头像文字
|
|
const avatarText = computed(() => {
|
|
if (props.name) {
|
|
// 如果是中文名,取最后一个字
|
|
if (/[\u4e00-\u9fa5]/.test(props.name)) {
|
|
return props.name.slice(-1)
|
|
}
|
|
// 如果是英文名,取首字母
|
|
return props.name.charAt(0).toUpperCase()
|
|
}
|
|
return '用'
|
|
})
|
|
|
|
const handleImageError = () => {
|
|
imageError.value = true
|
|
}
|
|
|
|
const handleImageLoad = () => {
|
|
imageError.value = false
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.safe-avatar {
|
|
border-radius: 50%;
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: #f0f0f0;
|
|
}
|
|
|
|
.safe-avatar img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.avatar-placeholder {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.avatar-text {
|
|
color: white;
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* 根据尺寸调整字体大小 */
|
|
.safe-avatar[style*="width: 24px"] .avatar-text {
|
|
font-size: 10px;
|
|
}
|
|
|
|
.safe-avatar[style*="width: 32px"] .avatar-text {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.safe-avatar[style*="width: 40px"] .avatar-text {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.safe-avatar[style*="width: 64px"] .avatar-text,
|
|
.safe-avatar[style*="width: 80px"] .avatar-text {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.safe-avatar[style*="width: 100px"] .avatar-text {
|
|
font-size: 24px;
|
|
}
|
|
</style>
|