UNPKG

@fesjs/fes-design

Version:
110 lines (100 loc) 3.58 kB
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 };