- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
Avatar 是 rsuite 中用于展示用户头像、品牌标识或占位图形的组件,配套的 AvatarGroup 用于组合展示多个头像。本文以 basic.md 示例 为起点,完整覆盖字符头像、图标头像、图片头像、尺寸、边框、颜色、加载失败回退、头像组堆叠与徽标等全部用法,并深入到 Avatar.tsx 源码、useImage.ts 与 Avatar.spec.tsx 测试用例,帮助你掌握其内部加载状态机与样式实现,可在真实业务中灵活组合使用。
一、组件概览与导入方式
Avatar 的完整组件文档位于 docs/pages/components/avatar/en-US/index.md,中文版见 docs/pages/components/avatar/zh-CN/index.md。文档页面将所有示例拆分为fragments/下的多个独立片段(basic.md、text.md 等),并通过<!--{include:\xxx.md`}-->` 指令由文档构建脚本注入渲染,因此每个片段都对应一个可独立运行的演示用例。
从组件库直接导入即可使用:
import { AvatarGroup, Avatar } from 'rsuite';Avatar与AvatarGroup均通过 src/Avatar/index.tsx 与src/AvatarGroup对外导出。注意在 basic.md 这类示例中使用了经典的ReactDOM.render写法,这只是文档演示环境的渲染方式,在实际 React 18+ 项目中请使用createRoot挂载:
import { createRoot } from 'react-dom/client'; import { AvatarGroup, Avatar } from 'rsuite'; const App = () => ( <AvatarGroup spacing={6}> <Avatar src="https://i.pravatar.cc/150?u=1" /> <Avatar circle /> <Avatar src="https://i.pravatar.cc/150?u=2" circle /> </AvatarGroup> ); createRoot(document.getElementById('root')).render(<App />);二、基本用法(Basic):图片、纯色占位与圆形
basic.md 演示了三种最常见的组合形态:
<AvatarGroup spacing={6}> <Avatar src="https://i.pravatar.cc/150?u=1" /> <Avatar circle /> <Avatar src="https://i.pravatar.cc/150?u=2" circle /> </AvatarGroup>- 第一个 Avatar 通过
src展示远程图片; - 第二个 Avatar 不传
src,会渲染一个内置的默认图标作为占位(AvatarIcon); - 第三个 Avatar 同时传入
src与circle,图片以圆形裁切展示。
circle属性在源码中通过样式类实现,见 src/Avatar/styles/index.scss:
& -circle { --rs-avatar-border-radius: var(--rs-radius-full); }即圆形头像只是把border-radius覆盖为--rs-radius-full(完整圆角),默认圆角为--rs-radius-sm。
加载失败时的默认占位
当未传入src或图片加载失败时,Avatar.tsx 会按以下优先级决定渲染内容:
const placeholder = children || altComponent || <AvatarIcon className={prefix`icon`} />; const image = loaded ? <img {...imageProps} className={prefix`image`} /> : placeholder;也就是说,children(文字或图标)优先于alt文案,alt文案优先于内置的AvatarIcon默认图标。这个逻辑与文档「Avatar Fallbacks」一节描述的两种回退完全一致,并有 测试用例 逐一验证。
三、字符头像与自定义背景(text.md)
当没有图片地址时,可以直接把文字或 Emoji 作为children传入,text.md 提供了两套典型写法:
<AvatarGroup spacing={6}> <Avatar color="green">R</Avatar> <Avatar bg="linear-gradient(45deg, #4CAF50, #2196F3)">X</Avatar> <Avatar color="blue">👍</Avatar> </AvatarGroup>关键点:
color用于设置头像背景色,可传主题色(如green、blue)或任意 CSS 颜色值;bg用于设置更复杂的背景,示例中使用了 CSS 线性渐变(linear-gradient);- 文本头像通常与
circle配合使用,形成圆形的字符头像,示例中第二组 AvatarGroup 展示了circle color="green"、circle bg="linear-gradient(...)"的写法。
color 与 bg 的实现差异
color属于AvatarProps的正式属性,类型为ColorScheme | CSSProperties['color'],见 Avatar.tsx,它会直接作用于StyledBox的背景色;bg并未出现在AvatarProps类型定义中,它是通过...rest透传给底层 Box 的样式属性,本质上等价于style={{ background: ... }}。因此在文档表格里看不到bg一行,但在实际使用中依然可用。
四、图标头像(icon.md)
图标头像通过children传入任意 React 图标元素即可,icon.md 使用的是react-icons生态的图标:
import { AvatarGroup, Avatar } from 'rsuite'; import { FaUserLarge } from 'react-icons/fa6'; import { FcBusinessman, FcCustomerSupport } from 'react-icons/fc'; <AvatarGroup spacing={6}> <Avatar><FaUserLarge /></Avatar> <Avatar><FaUserLarge size={30} /></Avatar> <Avatar><FcBusinessman size={30} /></Avatar> <Avatar><FcCustomerSupport size={30} /></Avatar> </AvatarGroup>从源码看,children的类型约束为string | Element<typeof Icon>(见 index.md 文档表格),说明官方设计意图就是支持文字与图标两种内容。图标大小可像示例中那样通过size属性直接控制。react-icons并非 rsuite 自带依赖,属于文档示例的独立选择,你可以替换为任何图标库或自定义 SVG。
五、图片头像与响应式图片(image.md)
image.md 展示了 10 个圆形图片头像的组合效果,这里把写法简化为两个核心形态:
<Avatar circle src="https://i.pravatar.cc/150?u=1" alt="Avatar" />图片头像相关的属性有五个(见 AvatarProps 定义):
| 属性 | 类型 | 说明 |
|---|---|---|
src | string | 图片地址 |
alt | string | 图片无法加载或未加载完成时的替代文案 |
srcSet | string | 响应式图片候选集,格式与原生img一致 |
sizes | string | 配合srcSet使用的媒体条件描述 |
imgProps | object | 透传给内部img元素的其他属性 |
其中srcSet、sizes、imgProps都会原样传给最终渲染的img元素(见 Avatar.tsx 的imageProps组装逻辑),测试用例 Avatar.spec.tsx 分别验证了srcset、sizes属性是否正确出现在 DOM 上:
<Avatar src="https://avatars.githubusercontent.com/u/19635045?s=48&v=4" srcSet=".../xxx 320w, .../xxx 480w" sizes="(max-width: 320px) 280px, (max-width: 480px) 440px, 800px" />六、尺寸控制(size.md)
size属性控制头像大小,可选值来自 rsuite 的 Size 类型:size.md 依次演示了xl、lg、md、sm、xs五个档位:
<Avatar size="xl" circle src="https://i.pravatar.cc/150?u=1" /> <Avatar size="lg" circle src="https://i.pravatar.cc/150?u=1" /> <Avatar size="md" circle src="https://i.pravatar.cc/150?u=1" /> <Avatar size="sm" circle src="https://i.pravatar.cc/150?u=1" /> <Avatar size="xs" circle src="https://i.pravatar.cc/150?u=1" />各档位的实际像素尺寸定义在 styles/index.scss:
| 档位 | 尺寸值 | 像素 |
|---|---|---|
xs | 1.25rem | 20px |
sm | 1.875rem | 30px |
md | 2.5rem(默认) | 40px |
lg | 3.75rem | 60px |
xl | 5.625rem | 90px |
2xl | 7.5rem | 120px |
默认尺寸为md(--rs-avatar-size变量默认指向--rs-avatar-size-md)。值得注意的是样式表中还定义了2xl档位,但文档示例与 Size 类型主要覆盖到xl。图片头像的img元素宽度、高度与行高均跟随--rs-avatar-size变量,因此换档位时图片会同步缩放。
七、带边框与颜色(bordered.md / color.md)
bordered(5.59.0 起支持)为头像添加一圈描边,bordered.md 的用法:
<Avatar bordered src="https://i.pravatar.cc/150?u=1" /> <Avatar bordered circle src="https://i.pravatar.cc/150?u=2" />边框样式来自 styles/index.scss,它使用了两层 CSS 变量组合的 box-shadow 实现环状描边效果:
&-bordered { box-shadow: var(--rs-avatar-ring-offset-shadow), var(--rs-avatar-ring-shadow), 0 0 #0000; }color(5.59.0 起支持)用于设置头像背景色,color.md 演示了 7 种主题色,并展示了「图片头像 + 颜色边框」与「纯色圆形头像」两种形态:
<Avatar color="red" bordered circle src="https://i.pravatar.cc/150?u=1" /> <Avatar color="orange" bordered circle src="https://i.pravatar.cc/150?u=1" /> {/* ... green / cyan / blue / violet ... */}color的类型为ColorScheme | CSSProperties['color'](见 Avatar.tsx),其中ColorScheme是 rsuite 预定义的主题色集合(red、orange、yellow、green、cyan、blue、violet 等),也可以传入任意 CSS 颜色字符串,例如color="#1675ff"。测试 Avatar.spec.tsx 通过testStyleProps验证了xs/sm/md/lg尺寸档位与red/green/blue/cyan/orange/yellow颜色档位的样式注入。
八、加载失败回退机制(fallback.md)
这是 Avatar 的核心健壮性设计。文档明确规定了两种回退顺序(见 zh-CN/index.md):
- 如果传入了
alt属性,图片加载失败时渲染alt文案; - 如果没有
alt,则渲染一个默认头像图标。
fallback.md 的对照实验:
<Avatar circle src="https://images.unsplash.com/broken" alt="Alt" /> <Avatar circle src="https://images.unsplash.com/broken" />- 第一个头像加载失败后显示
alt文案; - 第二个头像加载失败后显示默认图标。
底层原理:useImage 加载状态机
回退行为由 useImage.ts 这个 Hook 驱动。它内部维护一个四态状态机:
type Status = 'pending' | 'loading' | 'error' | 'loaded';- 无
src时状态为pending,直接渲染占位内容; - 有
src时状态变为loading,内部创建一个new Image()并监听onload/onerror(见 useImage.ts); - 加载成功状态变为
loaded,渲染真实img; - 加载失败状态变为
error,触发onError回调,此时loaded为false,Avatar 会渲染占位内容。
onError是 5.59.0 起支持的属性(Avatar.tsx),可用于埋点或自定义兜底逻辑:
<Avatar src="https://example.com/broken.png" onError={event => console.log('图片加载失败', event)} />对应的测试用例 Avatar.spec.tsx 覆盖了三种失败场景:无alt时渲染默认图标(rs-avatar-icon类、svg 标签、aria-label="Avatar")、有alt时渲染文案 span、有children时渲染 children。这印证了源码中placeholder = children || altComponent || <AvatarIcon/>的优先级。
九、头像组:堆叠与间距(stack.md)
AvatarGroup通过 React Context 向子级统一传递配置。在 AvatarGroup.tsx 中,它创建了AvatarGroupContext,并把size作为 context 值下发给每个 Avatar(size = groupSize的默认回退逻辑见 Avatar.tsx),因此:
- 在
AvatarGroup上设置size,可统一控制组内所有头像的尺寸; - 单独在某个
Avatar上设置size,可覆盖组的默认值。
spacing用于控制头像间距,内部转换为 CSS 变量注入:
const styles = mergeStyles(style, cssVar('spacing', spacing, getCssValue));堆叠(stack)模式
stack.md 演示了头像堆叠效果。第一组把所有用户头像直接堆叠展示:
<AvatarGroup stack> {users.map(user => ( <Avatar bordered circle key={user.name} src={user.avatar} alt={user.name} /> ))} </AvatarGroup>第二组只展示前 4 个头像,并用一个「+N」头像表示剩余数量,这是成员列表类页面的常见做法:
const max = 4; <AvatarGroup stack> {users.filter((user, i) => i < max).map(user => ( <Avatar bordered circle key={user.name} src={user.avatar} alt={user.name} /> ))} <Avatar bordered circle style={{ background: '#111' }}> +{users.length - max} </Avatar> </AvatarGroup>其中+6这个「计数头像」是一个纯文本头像,通过style直接指定深色背景(#111)。stack样式类由AvatarGroup的withPrefix({ stack })生成(见 AvatarGroup.tsx),spacing变量在堆叠模式下同样生效。
十、头像与徽标组合(badge.md)
Avatar 可以自由嵌套其他 rsuite 组件,badge.md 展示了与Badge组合的两种形态:
import { AvatarGroup, Badge, Avatar } from 'rsuite'; <AvatarGroup spacing={20}> <Badge> <Avatar src="https://i.pravatar.cc/150?u=1" /> </Badge> <Badge content="20"> <Avatar src="https://i.pravatar.cc/150?u=2" /> </Badge> </AvatarGroup>- 不带
content的Badge渲染一个纯圆点,适合表示「在线」状态; - 带
content="20"的Badge渲染数字角标,适合表示未读消息数。
十一、Props 完整参考
<Avatar>
| 属性 | 类型(默认值) | 说明 | 版本 |
|---|---|---|---|
alt | string | 图片头像加载失败时的替代文案 | — |
bordered | boolean | 是否显示边框 | 5.59.0 |
children | string | Element<typeof Icon> | 内容(文字或图标) | — |
circle | boolean | 以圆形显示 | — |
classPrefix | string('avatar') | 组件 CSS 类前缀 | — |
color | ColorScheme | CSSProperties['color'] | 设置头像背景色 | 5.59.0 |
imgProps | object | 应用于内部img元素的属性,可用于监听加载错误事件 | — |
onError | (event) => void | 图片加载失败回调 | 5.59.0 |
size | Size |('md') | 头像尺寸 | — |
sizes | string | img元素的sizes属性 | — |
src | string | img元素的src属性 | — |
srcSet | string | img元素的srcSet属性,用于响应式图片 | — |
<AvatarGroup>
| 属性 | 类型(默认值) | 说明 |
|---|---|---|
size | Size | 统一设置组内所有头像尺寸 |
spacing | number | 设置头像间距 |
stack | boolean | 以堆叠方式显示一组头像 |
其中Size类型对应xs / sm / md / lg / xl档位(样式层还额外支持2xl),ColorScheme对应red / orange / yellow / green / cyan / blue / violet等主题色,完整定义可参考 docs/pages/_common/types 目录下的公共类型说明。
十二、无障碍与可访问性细节
Avatar 源码在可访问性上有明确处理:
- 默认占位图标以
<svg role="img" aria-label="Avatar">渲染(见 AvatarIcon.tsx 与 Avatar.spec.tsx 的断言),让屏幕阅读器可感知; - 当提供
alt时,占位文案渲染为<span role="img" aria-label={alt}>(见 Avatar.tsx),aria-label取值为alt; AvatarGroup渲染时带有role="group"(见 AvatarGroup.tsx),语义化地标识一组头像。
因此,为图片头像补充有意义的alt(如用户名)不仅是体验需求,也直接提升了头像的可访问性。
十三、小结
从 basic.md 出发,Avatar 的完整能力可以归纳为:src图片头像、children文字/图标头像、circle圆形、size尺寸档位、bordered/color视觉定制、alt/onError失败回退,以及 AvatarGroup 的spacing、size继承与stack堆叠。底层实现上,图片加载由 useImage.ts 的四态状态机驱动,回退优先级为children > alt > 默认图标,这一行为在 Avatar.spec.tsx 中有完整测试覆盖。掌握这些用法与实现细节后,你可以在用户列表、成员管理、在线状态、通知角标等场景中直接落地。
- 前端
- UI组件
【免费下载链接】rsuite
🧱 A suite of React components .
相关推荐
RSUITE Avatar 组件完全指南:头像、头像组、回退策略与源码级原理解析
RSUITE Avatar 组件完全指南:头像、头像组、回退策略与源码级原理解析 本文基于 rsuite 开源仓库( gh_mirrors/rs/rsuite
前端UI组件Rsuite Avatar 头像组件实战指南:从图片加载回退到堆积头像组的完整实现解析
Rsuite Avatar 头像组件实战指南:从图片加载回退到堆积头像组的完整实现解析 本文围绕 Rsuite 官方 Avatar 组件文档展开,完整覆盖头像的
前端UI组件React Native Elements 头像组件(Avatar)完整指南:从基础用法到源码级原理
React Native Elements 头像组件(Avatar)完整指南:从基础用法到源码级原理 导读 本文以 React Native Elements(
UI组件移动开发前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考