Appearance
BizUserGroup 用户头像组
头像堆叠展示(无头像自动渲染姓名首字符):超过 max 收进 +N 气泡(hover/click 触发,含姓名与补充说明),成员可点击交互。任务协作者、审批链成员、动态作者行的展示件——与 BizTablePicker(管选择)成对。
基础用法
张李王 +2
张伟
前端组 · 负责人
李娜
后端组 · 接口开发
王强
测试组 · 用例评审
赵
赵敏产品组 · 需求 Owner
陈
陈晨运维组 · 发布窗口
3 人直观展示 + 超出收进 +N;
user-click 点击成员触发交互。<script setup lang="ts">
/** 基础用法:3 人直观展示 + 超出收进 +N,点击成员触发交互 */
import { ElMessage } from 'element-plus'
import { BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizUserGroupUser } from 'vue3-ep-biz-lib'
const users: BizUserGroupUser[] = [
{ name: '张伟', desc: '前端组 · 负责人' },
{ name: '李娜', desc: '后端组 · 接口开发' },
{ name: '王强', desc: '测试组 · 用例评审' },
{ name: '赵敏', desc: '产品组 · 需求 Owner' },
{ name: '陈晨', desc: '运维组 · 发布窗口' },
]
const onClick = (user: BizUserGroupUser): void => {
ElMessage.info(`点击成员:${user.name}`)
}
</script>
<template>
<div style="max-width: 560px">
<BizUserGroup :users="users" @user-click="onClick" />
</div>
</template>
显示代码
任务协作者
张李王 +1
张伟
主责
李娜
协作者
王强
协作者
赵
赵敏知会人
任务卡片场景:点击成员移出协作组(danger 提示二次确认),与 BizConfirmButton 组合。
<script setup lang="ts">
/** 场景:任务协作者——点击成员经二次确认移出协作组 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizConfirmButton, BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizUserGroupUser } from 'vue3-ep-biz-lib'
const members = ref<BizUserGroupUser[]>([
{ name: '张伟', desc: '主责' },
{ name: '李娜', desc: '协作者' },
{ name: '王强', desc: '协作者' },
{ name: '赵敏', desc: '知会人' },
])
const removing = ref<BizUserGroupUser | null>(null)
const onClick = (user: BizUserGroupUser): void => {
removing.value = user
}
const onConfirmRemove = (): void => {
if (removing.value === null) return
members.value = members.value.filter((m) => m !== removing.value)
ElMessage.success(`已将 ${removing.value.name} 移出协作组`)
removing.value = null
}
</script>
<template>
<div style="max-width: 560px; display: flex; align-items: center; gap: 16px">
<BizUserGroup :users="members" @user-click="onClick" />
<BizConfirmButton
v-if="removing !== null"
type="danger"
plain
size="small"
title="移出确认"
:message="`确认将 ${removing.name} 移出协作组?`"
@confirm="onConfirmRemove"
>
移出 {{ removing.name }}
</BizConfirmButton>
</div>
</template>
显示代码
审批链成员明细
周吴郑孙 +2
周正
部门经理 · 当前节点
吴岚
财务总监 · 下一节点
郑洁
法务审核
孙磊
总经理 · 终审
钱
钱进出纳打款
验
验收人使用部门 · 验收确认
悬浮头像查看该节点角色说明;+2 悬浮展开完整审批链
desc 补充部门/角色:头像悬浮即出明细气泡,审批链路一目了然。<script setup lang="ts">
/** 场景:审批链成员明细——desc 悬浮气泡展示部门/角色,大尺寸头像 */
import { BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizUserGroupUser } from 'vue3-ep-biz-lib'
const chain: BizUserGroupUser[] = [
{ name: '周正', desc: '部门经理 · 当前节点' },
{ name: '吴岚', desc: '财务总监 · 下一节点' },
{ name: '郑洁', desc: '法务审核' },
{ name: '孙磊', desc: '总经理 · 终审' },
{ name: '钱进', desc: '出纳打款' },
{ name: '验收人', desc: '使用部门 · 验收确认' },
]
</script>
<template>
<div style="max-width: 560px">
<BizUserGroup :users="chain" :max="4" :size="40" trigger="hover" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
悬浮头像查看该节点角色说明;+2 悬浮展开完整审批链
</div>
</div>
</template>
显示代码
悬浮查看全部
张李王赵陈 +6
张伟
前端 · 核心成员
李娜
后端 · 核心成员
王强
测试 · 核心成员
赵敏
产品 · 成员
陈晨
运维 · 成员
刘
刘磊UI · 成员
杨
杨静DBA · 成员
黄
黄勇安全 · 成员
周
周杰架构 · 成员
吴
吴芳项目经理 · 成员
徐
徐鹏文档 · 成员
11 人项目组:悬浮 +6 气泡展开全员(头像 + 姓名 + 角色)
trigger="hover" 悬浮 +N 展开全员列表(头像 + 姓名 + 说明)——10+ 人项目组的收纳展示。<script setup lang="ts">
/** 场景:悬浮查看全部——10+ 人项目组的收纳展示(+N 气泡全员列表) */
import { BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizUserGroupUser } from 'vue3-ep-biz-lib'
const roles = ['前端', '后端', '测试', '产品', '运维', 'UI', 'DBA', '安全', '架构', '项目经理', '文档']
const team: BizUserGroupUser[] = roles.map((role, i) => ({
name: `${['张', '李', '王', '赵', '陈', '刘', '杨', '黄', '周', '吴', '徐'][i]}${['伟', '娜', '强', '敏', '晨', '磊', '静', '勇', '杰', '芳', '鹏'][i]}`,
desc: `${role} · ${i < 3 ? '核心成员' : '成员'}`,
}))
</script>
<template>
<div style="max-width: 560px">
<BizUserGroup :users="team" :max="5" :size="28" />
<div style="margin-top: 8px; font-size: 13px; color: var(--el-text-color-secondary)">
11 人项目组:悬浮 +6 气泡展开全员(头像 + 姓名 + 角色)
</div>
</div>
</template>
显示代码
动态作者行
张李王 +1
4 人参与了讨论 · 最后回复 赵敏 · 2 小时前 赵
赵敏
信息流作者行混排:头像组 + 人数文案 + 时间,最后回复人高亮。
<script setup lang="ts">
/** 场景:动态作者行——头像组 + 人数文案 + 时间,最后回复人高亮 */
import { BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizUserGroupUser } from 'vue3-ep-biz-lib'
const participants: BizUserGroupUser[] = [
{ name: '张伟' },
{ name: '李娜' },
{ name: '王强' },
{ name: '赵敏' },
]
</script>
<template>
<div style="max-width: 560px; display: flex; align-items: center; gap: 8px">
<BizUserGroup :users="participants" :max="3" :size="24" />
<span style="font-size: 13px; color: var(--el-text-color-regular)">
{{ participants.length }} 人参与了讨论
</span>
<span style="font-size: 13px; color: var(--el-text-color-placeholder)">·</span>
<span style="font-size: 13px; color: var(--el-text-color-secondary)">
最后回复 <span style="color: var(--el-color-primary)">赵敏</span> · 2 小时前
</span>
</div>
</template>
显示代码
联动人员选择器
暂未选择成员
已选 0 人:点击头像即移除;点「选择成员」重选回填
BizTablePicker(tree 形态)选择 → BizUserGroup 回显的标准链路:选人、展示、移除闭环。
<script setup lang="ts">
/** 场景:联动人员选择器——BizTablePicker(tree 形态)选人 → BizUserGroup 回显、移除闭环 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizTablePicker, BizUserGroup } from 'vue3-ep-biz-lib'
import type { BizTablePickerChangePayload, BizTablePickerColumn, BizTablePickerParams, BizTablePickerResult, BizTablePickerRow } from 'vue3-ep-biz-lib'
const columns: BizTablePickerColumn[] = [
{ prop: 'name', label: '姓名', width: 120 },
{ prop: 'dept', label: '部门', minWidth: 140 },
]
const picked = ref<BizTablePickerRow[]>([])
const allMembers: BizTablePickerRow[] = [
{ id: 'u1', name: '张伟', dept: '前端组' },
{ id: 'u2', name: '李娜', dept: '后端组' },
{ id: 'u3', name: '王强', dept: '测试组' },
{ id: 'u4', name: '赵敏', dept: '产品组' },
{ id: 'u5', name: '陈晨', dept: '运维组' },
{ id: 'u6', name: '刘洋', dept: '前端组' },
]
/** 模拟选人回调(真实业务为接口分页查询) */
const requestMembers = (_params: BizTablePickerParams): Promise<BizTablePickerResult> =>
Promise.resolve({ list: allMembers, total: allMembers.length })
const onPicked = (payload: BizTablePickerChangePayload): void => {
ElMessage.success(`已选择 ${payload.selected.length} 人`)
}
const onRemove = (index: number): void => {
picked.value = picked.value.filter((_m, i) => i !== index)
}
</script>
<template>
<div style="max-width: 560px; display: flex; flex-direction: column; gap: 10px">
<div style="display: flex; align-items: center; gap: 12px">
<BizUserGroup :users="picked.map((m) => ({ name: String(m.name), desc: typeof m.dept === 'string' ? m.dept : undefined }))" @user-click="(_u, index) => onRemove(index)" />
<BizTablePicker
v-model="picked"
filter-mode="tree"
:columns="columns"
:request="requestMembers"
label-key="name"
multiple
trigger-text="选择成员"
empty-text="暂未选择成员"
@change="onPicked"
/>
</div>
<div style="font-size: 13px; color: var(--el-text-color-secondary)">
已选 {{ picked.length }} 人:点击头像即移除;点「选择成员」重选回填
</div>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| users | BizUserGroupUser[] | [] | 成员列表 |
| max | number | 3 | 直观展示人数上限(超出收进 +N 气泡) |
| size | number | 32 | 头像尺寸 px |
| trigger | 'hover' | 'click' | 'hover' | +N 气泡触发方式 |
BizUserGroupUser:{ name, avatar?, desc? }——无头像渲染姓名首字符;desc 为悬浮明细说明(部门/角色)。
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| user-click | (user: BizUserGroupUser, index: number) | 可见成员头像点击 |
Slots
| 插槽名 | 说明 |
|---|---|
| — | 无自定义插槽 |
Expose
| 属性/方法 | 说明 |
|---|---|
| — | 无暴露实例 |