- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
TDesign 小程序 UI 库(tdesign-miniprogram)中的 Avatar(头像)组件用于展示用户头像信息,除纯展示外还可点击进入个人详情等交互场景,其配套组件 AvatarGroup 支持多个头像的层叠展示与超出数量折叠。本文基于仓库内 Avatar 组件 API 文档 展开,完整覆盖两个组件的 Props、Events、Slots、External Classes 与 CSS Variables,并结合 avatar.ts、avatar-group.ts 等源码剖析父子关系继承、图片加载失败处理与级联偏移的底层实现。
一、组件概览与引入方式
根据 中文文档 的说明,Avatar 组件用于展示用户头像信息,且明确标注了渲染框架支持情况:Skyline、WebView 均支持。组件目录下同时提供微信原生小程序实现(packages/components/avatar)与 UniApp 适配实现(packages/uniapp-components/avatar),本文以微信原生小程序版本为准。
引入方式为在小程序的app.json(全局引入)或页面/组件的index.json(局部引入)中配置:
"usingComponents": { "t-avatar": "tdesign-miniprogram/avatar/avatar", "t-avatar-group": "tdesign-miniprogram/avatar-group/avatar-group" }二、头像类型与典型使用场景
组件文档给出了六类演示场景,对应仓库中 avatar 演示用例:
- 图片头像:传入
image属性展示网络/本地图片; - 字符头像:不传
image与icon,通过默认插槽传入文本(如用户昵称首字); - 图标头像:传入
icon属性,值为字符串时表示图标名称,值为Object时透传至 icon 组件; - 徽标头像:通过
badge-props在头像右上角叠加小红点或数字,继承 Badge 组件的全部特性; - 组合头像(纯展示 / 带操作):
t-avatar-group包裹多个t-avatar,可设置max折叠超出部分; - 头像尺寸:
size支持small/medium/large及任意px、rpx值。
从 avatar.wxml 的模板结构可以确认,内容渲染存在明确的优先级:
wx:if="{{image && isImgExist}}"—— 有图片地址且未标记加载失败时,渲染t-image(image-props可透传mode、lazy、loading、shape、webp、error等属性,默认mode为aspectFill);wx:elif判断_icon非空对象时,渲染 icon 模板;- 否则渲染
__text容器并挂载默认<slot />,用于字符头像或完全自定义内容。
三、Avatar API
Avatar Props
| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | alt | String | - | 头像替换文本,仅当图片加载失败时有效 | N | | badge-props | Object | - | 头像右上角提示信息,继承 Badge 组件的全部特性,如小红点或数字。TS 类型:BadgeProps,详见 Badge API 文档,详细类型定义 | N | | bordered | Boolean | false | 已废弃。是否显示外边框 | N | | hide-on-load-failed | Boolean | false | 加载失败时隐藏图片 | N | | icon | String / Object | - | 图标。值为字符串表示图标名称,值为Object类型时透传至icon| N | | image | String | - | 图片地址 | N | | image-props | Object | - | 透传至 Image 组件。TS 类型:ImageProps,详见 Image API 文档,详细类型定义 | N | | shape | String | - | 形状,可选项:circle/round。优先级高于 AvatarGroup.shape;Avatar 单独存在时默认值为 circle,父组件 AvatarGroup 存在时默认值由 AvatarGroup.shape 决定。TS 类型:ShapeEnum,通用类型定义 | N | | size | String | - | 尺寸,示例值:small/medium/large/24px/38px 等。优先级高于 AvatarGroup.size;Avatar 单独存在时默认值为 medium,父组件 AvatarGroup 存在时默认值由 AvatarGroup.size 决定 | N |
以上定义与 props.ts 中的实际注册值一一对应,例如alt默认值为''、hide-on-load-failed默认值为false、icon的 type 为null(同时接受 String 与 Object)。
Avatar Events
| 名称 | 参数 | 描述 | | -- | -- | -- | | error | - | 图片加载失败时触发 |
Avatar Slots
| 名称 | 描述 | | -- | -- | | - | 默认插槽,自定义内容区域内容 |
Avatar External Classes
| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 | | t-class-alt | 替代文本样式类 | | t-class-content | 内容样式类 | | t-class-icon | 图标样式类 | | t-class-image | 图片样式类 |
外部类在 avatar.ts#L15-L21 中注册,其中t-class-image作用于包裹图片/图标/文本的内层容器,是自定义头像背景与圆角的关键入口。
四、Avatar 源码实现剖析
4.1 与 AvatarGroup 的父子关系及属性继承
avatar.ts#L34-L47 通过relations声明了与avatar-group的 ancestor 关系:
relations: RelationsOptions = { '../avatar-group/avatar-group': { type: 'ancestor', linked(parent) { this.parent = parent; this.setData({ shape: this.data.shape || parent.data.shape || 'circle', size: this.data.size || parent.data.size, bordered: true, }); }, }, };这解释了文档中"shape/size 优先级高于 AvatarGroup"的语义:子组件自身设置时优先;未设置时回退到父组件的值;两者都没有时 shape 兜底为circle。同时可以看到,一旦头像处于组内,bordered会被强制置为true,即组合头像默认带白色描边分隔(对应 less 中的--border样式),这也是"组合头像层叠不粘连"的视觉基础。
4.2 图片加载失败处理与 error 事件
avatar.ts#L49-L64 中定义了两个 observers,配合 avatar.ts#L73-L78 的onLoadError方法构成完整的容错链路:
image变化时会重置isImgExist: true,源码注释明确说明目的是"避免切换后无法重新渲染"——即先失败的头像换回有效地址后能重新加载;onLoadError根据hideOnLoadFailed决定isImgExist(false 时图片节点从模板中消失,回退到 icon 或默认插槽文本);- 无论是否隐藏,都会
triggerEvent('error', e.detail),对应文档中的error事件,detail透传自 t-image 的错误信息。
4.3 尺寸与类名计算的 WXS 逻辑
avatar.wxs 在渲染层完成两个关键计算:
getClass:拼装--circle/--round形状类与--border-{size}边框类;当 size 含px时,边框宽度按medium档取值,保证自定义尺寸下边框视觉一致;getSize:以正则^([0-9]+)(px|rpx)$匹配自定义尺寸,rpx会按windowWidth * n / 750换算为 px,并按font-size = (px / 8) * 3 + 2动态计算文字字号——因此字符头像在任意自定义尺寸下都能保持比例协调。
预设尺寸的宽高、字号、边框宽度等均在 avatar.less 中以 CSS 变量方式定义,如 large 为 128rpx、medium 96rpx、small 80rpx。
五、AvatarGroup API
AvatarGroup Props
| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | style | Object | - | 样式 | N | | custom-style | Object | - | 样式,一般用于开启虚拟化组件节点场景 | N | | cascading | String | 'left-up' | 图片之间的层叠关系,可选值:左侧图片在上和右侧图片在上。可选项:left-up/right-up。TS 类型:CascadingValue,type CascadingValue = 'left-up' \| 'right-up',详细类型定义 | N | | collapse-avatar | String | - | 头像数量超出时,会出现一个头像折叠元素,该元素内容可自定义,默认为+N。示例:+5、...、更多| N | | max | Number | - | 能够同时显示的最多头像数量 | N | | shape | String | - | 形状,优先级低于 Avatar.shape。可选项:circle/round。TS 类型:ShapeEnum,通用类型定义 | N | | size | String | - | 尺寸,示例值:small/medium/large/24px/38px 等。优先级低于 Avatar.size | N |
AvatarGroup Events
| 名称 | 参数 | 描述 | | -- | -- | -- | | collapsed-item-click | - | 点击头像折叠元素触发 |
AvatarGroup Slots
| 名称 | 描述 | | -- | -- | | - | 默认插槽,自定义内容区域内容 | | collapse-avatar | 自定义collapse-avatar显示内容 |
AvatarGroup External Classes
| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 | | t-class-content | 内容样式类 | | t-class-image | 图片样式类 |
六、AvatarGroup 源码实现剖析
6.1 级联层叠的偏移类计算
avatar-group.ts#L51-L64 的setClass方法解析cascading参数并生成根节点类名:
const direction = cascading.split('-')[0]; // 'left' | 'right' const classList = [ name, `${prefix}-class`, `${name}-offset-${direction}`, `${name}-offset-${direction}-${size.indexOf('px') > -1 ? 'medium' : size || 'medium'}`, ];即cascading="left-up"会生成t-avatar-group-offset-left t-avatar-group-offset-left-medium。配合 avatar-group.less:偏移量通过 CSS 变量--td-avatar-margin-left注入到每个头像 wrapper 的margin-left上(三种尺寸均为calc(-1 * @spacer)),形成负向重叠;z-index 则通过 Less 递归 mixin.generate-z-index按nth-child逐个递减(初始值 50),从而实现"左侧在上"的层叠次序;right-up时方向反转,视觉上变为右侧在上。cascading、size任一变化都会通过 observers 重新触发setClass。
6.2 max 截断与折叠元素
avatar-group.ts#L66-L76 的handleMax在ready阶段执行:
handleMax() { const { max } = this.data; const len = this.$children.length; if (!max || max > len) return; const restAvatars = this.$children.splice(max, len - max); restAvatars.forEach((child) => { child.hide(); // 子组件内 setData({ isShow: false }),wrapper 变为 display:none }); }被截断的头像并非从 DOM 中移除,而是调用子组件的hide()方法以display: none隐藏(见 avatar.wxs#L27-L29 的getStyles),这样保留节点状态,头像动态增删时逻辑仍然可恢复。
折叠元素在 avatar-group.wxml 中:当max && max < length时渲染默认折叠元素,其内部是一个icon="user-add"的t-avatar加上collapseAvatar文本(未传文本时仅显示user-add图标,配合样式呈现+N效果);bindtap="onCollapsedItemClick"触发collapsed-item-click事件。若开发者通过collapse-avatar命名插槽注入了自定义内容,less 中__collapse--slot:not(:empty) + __collapse--default { display: none }的规则会让默认折叠元素自动隐藏,两种展示方式互斥且无缝切换。
七、CSS Variables 自定义样式
组件提供了下列 CSS 变量,可用于自定义样式(默认值与 avatar.less、avatar-group.less 中的 Less 变量映射一致):
| 名称 | 默认值 | 说明 | | -- | -- | -- | | --td-avatar-group-init-z-index | 50 | 组合头像初始 z-index,递归递减生成层叠次序 | | --td-avatar-group-line-spacing | calc(@spacer / 4) | 组合头像上下留白(wrapper padding) | | --td-avatar-group-margin-left-large | calc(-1 * @spacer) | large 尺寸组合头像重叠偏移量 | | --td-avatar-group-margin-left-medium | calc(-1 * @spacer) | medium 尺寸组合头像重叠偏移量 | | --td-avatar-group-margin-left-small | calc(-1 * @spacer) | small 尺寸组合头像重叠偏移量 | | --td-avatar-bg-color | @brand-color-light-active | 头像背景色 | | --td-avatar-border-color | #fff | 头像边框颜色 | | --td-avatar-border-width-large | 6rpx | 大尺寸边框宽度 | | --td-avatar-border-width-medium | 4rpx | 中尺寸边框宽度 | | --td-avatar-border-width-small | 2rpx | 小尺寸边框宽度 | | --td-avatar-circle-border-radius | @radius-circle | 圆形头像圆角 | | --td-avatar-content-color | @brand-color | 头像文字颜色 | | --td-avatar-icon-large-font-size | 64rpx | large 图标字号 | | --td-avatar-icon-medium-font-size | 48rpx | medium 图标字号 | | --td-avatar-icon-small-font-size | @font-size-xl | small 图标字号 | | --td-avatar-large-width | 128rpx | large 头像宽高 | | --td-avatar-margin-left | 0 | 单个头像左边距(组内被 offset 类覆写) | | --td-avatar-medium-width | 96rpx | medium 头像宽高 | | --td-avatar-round-border-radius | @radius-default | 方形圆角头像圆角 | | --td-avatar-small-width | 80rpx | small 头像宽高 | | --td-avatar-text-large-font-size | @font-size-xl | large 文字字号 | | --td-avatar-text-medium-font-size | @font-size-m | medium 文字字号 | | --td-avatar-text-small-font-size | @font-size-base | small 文字字号 |
由于所有 Less 变量均以var(--td-xxx, 默认值)形式消费,开发者只需在页面或组件样式中覆写对应变量(如--td-avatar-bg-color、--td-avatar-border-width-medium),即可在不改动组件源码的情况下定制外观。
八、小结与相关文件
Avatar 组件的核心设计可以概括为三点:内容三级回退(image → icon → 插槽文本)、属性优先级继承(Avatar 自身属性 > AvatarGroup 继承值 > 内置默认值)、状态化容错(加载失败标记可随 image 变化自动重置)。AvatarGroup 则通过负 margin + 递减 z-index 实现级联层叠,通过hide()软隐藏 + 折叠元素实现max截断,并保留collapse-avatar插槽与collapsed-item-click事件用于业务定制。
本文引用的仓库文件清单:
- packages/components/avatar/README.en-US.md:英文 API 文档(本文主体)
- packages/components/avatar/README.md:中文文档与演示说明
- packages/components/avatar/avatar.ts:组件逻辑(relations/observers/error 处理)
- packages/components/avatar/avatar.wxml:渲染模板与内容优先级
- packages/components/avatar/avatar.wxs:类名与自定义尺寸计算
- packages/components/avatar/avatar.less:样式与 CSS 变量
- packages/components/avatar/props.ts 与 packages/components/avatar/type.ts:属性注册与 TS 类型
- packages/components/avatar-group/avatar-group.ts:分组逻辑(setClass/handleMax)
- packages/components/avatar-group/avatar-group.wxml:折叠元素模板
- packages/components/avatar-group/avatar-group.less:级联偏移与 z-index 生成
- packages/components/avatar-group/props.ts 与 packages/components/avatar-group/type.ts:分组属性与
CascadingValue类型 - packages/components/avatar/test:组件测试与演示用例
- 前端
- UI组件
- 小程序
- 设计系统
- 移动开发
【免费下载链接】tdesign-miniprogram
Wechat MiniProgram and Uniapp UI components lib for TDesign
相关推荐
Ant Design Blazor Avatar 组件完整指南:图片、图标、字符与 AvatarGroup 头像组实战
Ant Design Blazor Avatar 组件完整指南:图片、图标、字符与 AvatarGroup 头像组实战 Avatars(头像)用于代表用户、人物
UI组件前端Semi Design Avatar 头像组件完全指南:尺寸、颜色、Slot 扩展与 AvatarGroup 头像组实战
Semi Design Avatar 头像组件完全指南:尺寸、颜色、Slot 扩展与 AvatarGroup 头像组实战 Avatar(头像)是 Semi De
前端UI组件设计系统Varlet AvatarGroup 头像组组件详解:头像堆叠偏移、垂直排列与源码实现原理
Varlet AvatarGroup 头像组组件详解:头像堆叠偏移、垂直排列与源码实现原理 头像组(AvatarGroup)是 Varlet 移动端/桌面端组件
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考