Element Plus Avatar 头像组件完全指南:基本用法、图片降级回退与 AvatarGroup 头像组
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
Element Plus 的 Avatar(头像)组件用于在界面中直观地表示用户、组织或任意对象,支持图片、图标(Icon)与文本字符三种渲染形态。本文以 docs/en-US/component/avatar.md 为骨架,结合 packages/components/avatar 的源码实现、测试用例与 docs/examples/avatar 官方示例,系统讲解 Avatar 的尺寸/形状控制、图片适配、加载失败回退机制,以及 2.13.1 起新增的 AvatarGroup 头像组折叠能力,帮助你在一线业务中正确、高效地使用该组件。
组件概述
Avatar 是 Element Plus 组件库中用于展示人物或对象标识的轻量级组件。它在渲染上始终是一个<span>容器,并根据传入的内容类型决定内部节点:
- 传入
src/srcSet且图片未加载失败时,渲染<img>图片元素; - 否则传入
icon时渲染<el-icon>图标; - 两者都没有时渲染默认插槽中的字符内容。
这一渲染优先级在 avatar.vue 模板 中体现得十分直观:v-if="(src || srcSet) && !hasLoadError"→v-else-if="icon"→v-else(默认插槽)。组件对外注册名称为ElAvatar,包入口位于 packages/components/avatar/index.ts,并配有独立的style子包。头像的视觉尺寸、圆角、背景与文字颜色均由主题变量驱动,可在 packages/theme-chalk/src/avatar.scss 中查看其样式定义。
基本用法:shape 与 size
Avatar 通过shape与size两个属性控制外观:
shape:头像形状,可选circle(圆形,默认)或square(圆角方形)。size:头像尺寸,可以是number(数字像素值,如 50),也可以是'large' | 'default' | 'small'三个预设枚举。
参考官方示例 docs/examples/avatar/basic.vue,一个覆盖圆形/方形与多尺寸的头像集合写法如下:
<template> <div class="demo-basic"> <div class="sub-title">circle</div> <div class="demo-basic--circle"> <el-avatar :size="50" :src="circleUrl" /> <el-avatar :size="'small'" :src="circleUrl" /> <el-avatar :src="circleUrl" /> <el-avatar :size="'large'" :src="circleUrl" /> </div> <div class="sub-title">square</div> <div class="demo-basic--circle"> <el-avatar shape="square" :size="50" :src="squareUrl" /> <el-avatar shape="square" :size="'small'" :src="squareUrl" /> <el-avatar shape="square" :src="squareUrl" /> <el-avatar shape="square" :size="'large'" :src="squareUrl" /> </div> </div> </template>尺寸的底层实现
从 avatar.ts 的属性定义可以看到,size同时接受Number与String类型,并对字符串做了componentSizes枚举校验。而在 avatar.vue 中,尺寸的实现方式分为两种:
- 数字尺寸:通过 CSS 变量
--el-avatar-size注入,即sizeStyle计算属性中的ns.cssVarBlock({ size: addUnit(size.value) }),将数字自动补上px单位; - 枚举尺寸:直接挂载修饰类名
el-avatar--small/el-avatar--large,由 SCSS 在 avatar.scss 中通过@each $size in (small, large)覆盖--el-avatar-size变量。
对应的单元测试(avatar.test.tsx)也验证了这两种路径:数字 50 时断言内联样式包含--el-avatar-size: 50px;,字符串'small'时断言类名包含el-avatar--small。
三种类型:图片、图标与字符
Avatar 支持的三种内容形态见官方示例 docs/examples/avatar/types.vue:
<template> <div class="demo-type"> <div> <el-avatar :icon="UserFilled" /> </div> <div> <el-avatar src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" /> </div> <div> <el-avatar> user </el-avatar> </div> </div> </template> <script setup lang="ts"> import { UserFilled } from '@element-plus/icons-vue' </script>- 图片头像:传入
src,可选配合alt、src-set、fit; - 图标头像:传入
icon,其类型为string | Component(iconPropType),可直接引用 @element-plus/icons-vue 提供的图标组件; - 字符头像:不传
src与icon,直接在使用处放入文本(如用户名首字母),通过默认插槽渲染。
图标模式会额外追加el-avatar--icon修饰类(见 avatar.vue),并放大字号以适配--el-avatar-icon-size。测试 avatar.test.tsx 验证了icon={markRaw(User)}会渲染出图标组件且带el-avatar--icon类。
Fallback:图片加载失败回退
当图片头像的src加载出错时,Avatar 会触发error事件并提供回退渲染能力。
事件与回退机制
error事件在 avatar.ts 中定义为(e: Event) => void。底层逻辑位于 avatar.vue:图片触发原生error时,hasLoadError置为true(同时抛出error事件),模板据此隐藏<img>,转而渲染icon或默认插槽中的回退内容。
官方回退示例 docs/examples/avatar/fallback.vue 中,图片加载失败后在插槽内放置一张本地备选图片:
<template> <div class="demo-type"> <el-avatar :size="60" src="https://empty" @error="errorHandler"> <img src="https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png" /> </el-avatar> </div> </template> <script lang="ts" setup> const errorHandler = () => true </script>关键细节:src 变更后自动复位
一个容易踩坑的细节是:当src或srcSet发生变化时,组件会通过watch将hasLoadError自动重置为false(avatar.vue),从而允许重新加载新图片。测试用例 avatar.test.tsx 覆盖了src与srcSet两条路径:从失败地址切换到成功地址后,hasLoadError恢复为false且<img>重新出现。这意味着在头像地址动态变化(如用户更换头像)的场景下,无需手动重置组件状态。
Fit Container:图片适配方式
对于图片头像,fit属性控制图片如何适配容器,语义与 CSSobject-fit完全一致,可选值:
| 值 | 效果 |
|---|---|
fill | 拉伸填充,可能变形 |
contain | 等比缩放完整显示,可能留有空白 |
cover | 等比缩放铺满容器,裁切溢出部分(默认值) |
none | 保持原始尺寸,不做缩放 |
scale-down | 取none与contain中较小的结果 |
在源码中,fit的默认值为'cover'(avatar.ts),渲染时直接以内联样式object-fit: fit应用到<img>上(avatar.vue)。官方示例 docs/examples/avatar/fit.vue 以方形100px头像遍历展示五种适配效果,测试用例 avatar.test.tsx 也逐一断言了五种fit值对应的内联object-fit样式。
Avatar Group 头像组(2.13.1+)
从 2.13.1 版本起,Element Plus 提供了<el-avatar-group>用于将多个头像成组展示,并支持折叠(collapse)能力,见官方示例 docs/examples/avatar/group.vue。
基础分组
<template> <div class="m-4"> <el-avatar-group> <el-avatar v-for="number in 5" :key="number" :src="circleUrl" /> </el-avatar-group> </div> </template>el-avatar-group会通过 Vue 的provide向下注入size与shape上下文(avatar-group.tsx、constants.ts),组内未显式声明size/shape的单个 Avatar 会自动继承组的设置;单个头像显式传入时则覆盖组级配置(avatar.vue)。测试 avatar.test.tsx 验证了组级size="small"、shape="square"与个别头像large/circle覆盖的类名组合。
折叠与 Tooltip 提示
头像组还提供一组折叠相关属性:
collapse-avatars:是否折叠超出数量的头像,默认false;max-collapse-avatars:最多展示的头像数量,默认1(需配合collapse-avatars使用);collapse-avatars-tooltip:鼠标悬停折叠头像时,是否通过 Tooltip 展示所有被隐藏的头像(需配合collapse-avatars使用);effect:Tooltip 主题,内置dark/light,默认light;placement:Tooltip 出现位置,支持top、top-start、top-end、bottom、bottom-start、bottom-end、left、left-start、left-end、right、right-start、right-end,默认top;popper-class/popper-style:Tooltip 自定义类名与样式;collapse-class/collapse-style:折叠头像自身的自定义类名与样式。
折叠判定逻辑在 avatar-group.tsx:当collapseAvatars为真且头像数量大于maxCollapseAvatars时,将超出部分替换为一个内容为+ N(N 为隐藏数量)的折叠头像;若开启collapseAvatarsTooltip,则用ElTooltip包裹,Tooltip 内容中逐一会话式(cloneVNode)渲染所有隐藏头像。注意折叠头像会显式继承组的size/shape,因此在使用max-collapse-avatars时其尺寸可能与组内其他头像保持一致。
一个综合使用示例(摘自 docs/examples/avatar/group.vue):
<template> <div class="m-4"> <p>use collapse-avatars-tooltip</p> <el-avatar-group collapse-avatars :max-collapse-avatars="3" collapse-avatars-tooltip > <el-avatar v-for="number in 5" :key="number" :src="circleUrl" /> </el-avatar-group> </div> </template>对应测试 avatar.test.tsx 验证了折叠头像触发mouseenter后 Tooltip 出现并包含头像内容。属性定义完整清单见 avatar-group-props.ts,其中popperClass/popperStyle直接复用了 Tooltip 的内容属性定义(useTooltipContentProps),保证了两组件样式行为的一致性。
API 速查
Avatar Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| icon | 图标类型头像的图标,详见 Icon 组件 | string/Component | — |
| size | 头像尺寸 | number/'large' \| 'default' \| 'small' | — |
| shape | 头像形状 | 'circle' \| 'square' | — |
| src | 图片头像的图片来源 | string | — |
| src-set | 图片头像的原生srcset属性 | string | — |
| alt | 图片头像的原生alt属性 | string | — |
| fit | 图片如何适配容器(同 CSSobject-fit) | 'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale-down' | cover |
Avatar Events
| 名称 | 说明 | 类型 |
|---|---|---|
| error | 图片加载失败时触发 | (e: Event) => void |
Avatar Slots
| 名称 | 说明 |
|---|---|
| default | 自定义头像内容 |
AvatarGroup Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| size | 控制组内头像尺寸 | number/'large' \| 'default' \| 'small' | — |
| shape | 控制组内头像形状 | 'circle' \| 'square' | — |
| collapse-avatars | 是否折叠头像 | boolean | false |
| collapse-avatars-tooltip | 悬停折叠头像时是否展示全部被折叠头像(需collapse-avatars为 true) | boolean | false |
| max-collapse-avatars | 最多展示的头像数量(需collapse-avatars为 true) | number | 1 |
| effect | Tooltip 主题 | 'dark' \| 'light'/string | light |
| placement | Tooltip 位置 | 'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end' | top |
| popper-class | Tooltip 自定义类名 | string | '' |
| popper-style | Tooltip 自定义样式 | string/object | — |
| collapse-class | 折叠头像自定义类名 | string | '' |
| collapse-style | 折叠头像自定义样式 | string/object | — |
小结与延伸阅读
Avatar 虽小,但设计上覆盖了「内容形态切换、尺寸变量化、加载失败回退、组级上下文继承、折叠 + Tooltip」等完整场景。想深入探究实现细节,可按以下路径继续阅读当前仓库:
- 组件声明与类型:packages/components/avatar/src/avatar.ts、packages/components/avatar/src/avatar-group-props.ts
- 渲染与逻辑:packages/components/avatar/src/avatar.vue、packages/components/avatar/src/avatar-group.tsx
- 测试用例:packages/components/avatar/tests/avatar.test.tsx
- 样式变量:packages/theme-chalk/src/avatar.scss
- 官方示例:docs/examples/avatar 目录下的
basic.vue、types.vue、fallback.vue、fit.vue、group.vue
在实际项目中,建议优先为头像设置统一尺寸枚举或明确的数字像素值,并为图片头像预留@error回退内容;当头像数量较多(如参与成员、群成员列表)时,直接启用collapse-avatars+collapse-avatars-tooltip组合即可获得整洁且信息完整的展示效果。
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考