@fesjs/fes-design
Version:
fes-design for PC
110 lines (100 loc) • 3.58 kB
JavaScript
import { defineComponent, computed, ref, watch, onMounted, nextTick, onUpdated, createVNode } from 'vue';
import getPrefixCls from '../_util/getPrefixCls';
import { PictureFailOutlined } from '../icon';
import { useTheme } from '../_theme/useTheme';
import { avatarProps } from './props';
import { sizeMap } from './const';
const prefixCls = getPrefixCls('avatar');
var avatar = defineComponent({
name: 'FAvatar',
props: avatarProps,
emits: ['error'],
setup(props, _ref) {
let {
emit,
slots
} = _ref;
useTheme();
const avatarCls = computed(() => {
return [`${prefixCls}`, props.shape === 'square' ? `${prefixCls}-shape-square` : `${prefixCls}-shape-circle`];
});
const avatarSize = computed(() => {
var _sizeMap$props$size;
return typeof props.size === 'number' ? props.size : (_sizeMap$props$size = sizeMap[props.size]) !== null && _sizeMap$props$size !== void 0 ? _sizeMap$props$size : sizeMap.middle;
});
const avatarStyle = computed(() => {
return {
width: `${avatarSize.value}px`,
height: `${avatarSize.value}px`,
backgroundColor: props.backgroundColor,
color: props.color
};
});
const avatarRef = ref(null);
const contentRef = ref(null);
// 动态缩放字体
const adjustFontSize = (element, contentElement) => {
if (!element || !contentElement) {
return;
}
// 计算并设置缩放值
const parentWidth = element.offsetWidth;
const contentWidth = contentElement.scrollWidth;
const scaleVal = parentWidth * 0.7 / contentWidth; // 始终保持最大宽度的70%,这个数值比较美观
contentElement.style.transform = `scale(${scaleVal})`;
};
// 图片加载失败,且没有兜底图片
const imgLoadingFailed = ref(false);
// 设定图片如何在容器中展示
const imgStyle = computed(() => {
return {
objectFit: props.fit
};
});
// 渲染头像图片
const renderImg = () => {
let fallbackAttempted = false;
// img 加载出错回调
const handleError = event => {
if (props.fallbackSrc && !fallbackAttempted) {
// 替换成错误场景的图片路径
event.target.src = props.fallbackSrc;
fallbackAttempted = true;
} else {
imgLoadingFailed.value = true;
}
// 调用外部传进来的error回调
emit('error');
};
return createVNode("img", {
"src": props.src,
"style": imgStyle.value,
"onError": handleError
}, null);
};
watch(() => props.src, () => {
imgLoadingFailed.value = false;
});
onMounted(async () => {
await nextTick();
adjustFontSize(avatarRef.value, contentRef.value); // 在组件挂载后调整字体大小
});
onUpdated(async () => {
await nextTick();
adjustFontSize(avatarRef.value, contentRef.value);
});
return () => {
var _slots$default;
return createVNode("div", {
"ref": avatarRef,
"class": avatarCls.value,
"style": avatarStyle.value
}, [createVNode("div", {
"ref": contentRef,
"class": `${prefixCls}-content`
}, [(_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots)]), props.src ? imgLoadingFailed.value ? // 图片加载失败,且没有兜底图片
createVNode(PictureFailOutlined, null, null) : renderImg() : null]);
};
}
});
export { avatar as default };