mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-15 01:41:20 +08:00
55348b30b6
* style: use prettier * style: just prettier format, no code changes * style: eslint fix object-shorthand, prefer-const * style: fix no-void * style: no-console
110 lines
2.4 KiB
Vue
110 lines
2.4 KiB
Vue
<template>
|
|
<span :class="avatarClass" :style="sizeStyle">
|
|
<img
|
|
v-if="(src || srcSet) && !hasLoadError"
|
|
:src="src"
|
|
:alt="alt"
|
|
:srcset="srcSet"
|
|
:style="fitStyle"
|
|
@error="handleError"
|
|
/>
|
|
<i v-else-if="icon" :class="icon"></i>
|
|
<slot v-else></slot>
|
|
</span>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, computed, ref, watch, toRef } from 'vue'
|
|
import type { CSSProperties, PropType } from 'vue'
|
|
|
|
const ERROR_EVENT = 'error'
|
|
export default defineComponent({
|
|
name: 'ElAvatar',
|
|
props: {
|
|
size: {
|
|
type: [Number, String] as PropType<number | string>,
|
|
validator(this: never, val: unknown) {
|
|
if (typeof val === 'string') {
|
|
return ['large', 'medium', 'small'].includes(val)
|
|
}
|
|
return typeof val === 'number'
|
|
},
|
|
default: 'large',
|
|
},
|
|
shape: {
|
|
type: String,
|
|
default: 'circle',
|
|
validator(this: never, val: string) {
|
|
return ['circle', 'square'].includes(val)
|
|
},
|
|
},
|
|
icon: String,
|
|
src: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
alt: String,
|
|
srcSet: String,
|
|
fit: {
|
|
type: String,
|
|
default: 'cover',
|
|
},
|
|
},
|
|
emits: [ERROR_EVENT],
|
|
setup(props, { emit }) {
|
|
const hasLoadError = ref(false)
|
|
|
|
const src = toRef(props, 'src')
|
|
// need reset hasLoadError to false if src changed
|
|
watch(src, () => {
|
|
hasLoadError.value = false
|
|
})
|
|
|
|
const avatarClass = computed(() => {
|
|
const { size, icon, shape } = props
|
|
const classList = ['el-avatar']
|
|
if (size && typeof size === 'string') {
|
|
classList.push(`el-avatar--${size}`)
|
|
}
|
|
if (icon) {
|
|
classList.push('el-avatar--icon')
|
|
}
|
|
if (shape) {
|
|
classList.push(`el-avatar--${shape}`)
|
|
}
|
|
return classList
|
|
})
|
|
|
|
const sizeStyle = computed(() => {
|
|
const { size } = props
|
|
return typeof size === 'number'
|
|
? {
|
|
height: `${size}px`,
|
|
width: `${size}px`,
|
|
lineHeight: `${size}px`,
|
|
}
|
|
: {}
|
|
})
|
|
|
|
const fitStyle = computed(
|
|
() =>
|
|
({
|
|
objectFit: props.fit,
|
|
} as CSSProperties)
|
|
)
|
|
|
|
function handleError(e: Event) {
|
|
hasLoadError.value = true
|
|
emit(ERROR_EVENT, e)
|
|
}
|
|
return {
|
|
hasLoadError,
|
|
avatarClass,
|
|
sizeStyle,
|
|
handleError,
|
|
fitStyle,
|
|
}
|
|
},
|
|
})
|
|
</script>
|