9.2 KiB
9.2 KiB
InfoPanel 组件
组件说明
信息展示面板组件,用于以网格布局展示数据的字段信息,支持自定义字段渲染和操作按钮。常用于详情页面或抽屉中展示结构化数据。
组件位置
src/components/InfoPanel/InfoPanel.jsx
src/components/InfoPanel/InfoPanel.css
参数说明
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| data | Object | 是 | - | 数据源对象 |
| fields | Array | 否 | [] | 字段配置数组 |
| actions | Array | 否 | [] | 操作按钮配置数组 |
| gutter | Array | 否 | [24, 16] | Grid 网格间距 [水平, 垂直] |
FieldConfig 配置项
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 数据字段名 |
| label | string | 是 | 字段显示标签 |
| span | number | 否 | 网格占位份数(24栅格系统),默认 6 |
| render | function(value, data) | 否 | 自定义渲染函数 |
ActionConfig 配置项
| 属性名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | string | 是 | 按钮唯一标识 |
| label | string | 是 | 按钮文本 |
| icon | ReactNode | 否 | 按钮图标 |
| type | string | 否 | 按钮类型(primary/default/dashed/text/link) |
| danger | boolean | 否 | 是否为危险按钮 |
| disabled | boolean | 否 | 是否禁用 |
| onClick | function | 否 | 点击回调函数 |
使用示例
基础用法
import InfoPanel from '../components/InfoPanel/InfoPanel'
function UserDetail() {
const userData = {
userName: 'admin',
name: '系统管理员',
group: '管理员组',
userType: '管理员',
status: 'enabled',
grantedTerminals: 8,
grantedImages: 21,
}
const userFields = [
{ key: 'userName', label: '用户名', span: 6 },
{ key: 'name', label: '姓名', span: 6 },
{ key: 'group', label: '用户分组', span: 6 },
{ key: 'userType', label: '用户类型', span: 6 },
{ key: 'grantedTerminals', label: '授权终端', span: 6 },
{ key: 'grantedImages', label: '授权镜像', span: 6 },
]
return <InfoPanel data={userData} fields={userFields} />
}
自定义字段渲染
import { Tag } from 'antd'
const userFields = [
{ key: 'userName', label: '用户名', span: 6 },
{ key: 'name', label: '姓名', span: 6 },
{
key: 'status',
label: '状态',
span: 6,
render: (value) => (
<Tag color={value === 'enabled' ? 'green' : 'default'}>
{value === 'enabled' ? '启用' : '停用'}
</Tag>
),
},
{
key: 'description',
label: '描述',
span: 18,
render: (value) => value || '--', // 空值显示默认占位符
},
]
<InfoPanel data={userData} fields={userFields} />
带操作按钮
import { LockOutlined } from '@ant-design/icons'
<InfoPanel
data={userData}
fields={userFields}
actions={[
{
key: 'move',
label: '转移分组',
type: 'primary',
onClick: () => console.log('转移分组'),
},
{
key: 'blacklist',
label: '加入黑名单',
onClick: () => console.log('加入黑名单'),
},
{
key: 'reset',
label: '重置密码',
onClick: () => console.log('重置密码'),
},
{
key: 'disable',
label: '停用',
icon: <LockOutlined />,
onClick: () => console.log('停用'),
},
]}
/>
配合 DetailDrawer 使用
import DetailDrawer from '../components/DetailDrawer/DetailDrawer'
import InfoPanel from '../components/InfoPanel/InfoPanel'
import { Tag } from 'antd'
function UserListPage() {
const [showDetailDrawer, setShowDetailDrawer] = useState(false)
const [selectedUser, setSelectedUser] = useState(null)
const userFields = [
{ key: 'userName', label: '用户名', span: 6 },
{ key: 'group', label: '用户分组', span: 6 },
{ key: 'name', label: '姓名', span: 6 },
{ key: 'grantedImages', label: '授权镜像', span: 6 },
{ key: 'userType', label: '用户类型', span: 6 },
{ key: 'grantedTerminals', label: '授权终端', span: 6 },
{
key: 'status',
label: '启停用',
span: 6,
render: (value) => (
<Tag color={value === 'enabled' ? 'green' : 'default'}>
{value === 'enabled' ? '启用' : '停用'}
</Tag>
),
},
{ key: 'description', label: '描述', span: 18, render: () => '--' },
]
return (
<DetailDrawer
visible={showDetailDrawer}
onClose={() => setShowDetailDrawer(false)}
title={{
text: selectedUser?.userName || '',
}}
>
<InfoPanel
data={selectedUser}
fields={userFields}
actions={[
{ key: 'move', label: '转移分组', type: 'primary', onClick: () => console.log('转移分组') },
{ key: 'blacklist', label: '加入黑名单', onClick: () => console.log('加入黑名单') },
{ key: 'reset', label: '重置密码', onClick: () => console.log('重置密码') },
{ key: 'disable', label: '停用', onClick: () => console.log('停用') },
]}
/>
</DetailDrawer>
)
}
不同 span 值的布局
// 24栅格系统,一行总共24份
const fields = [
{ key: 'field1', label: '字段1', span: 6 }, // 占1/4宽度
{ key: 'field2', label: '字段2', span: 6 }, // 占1/4宽度
{ key: 'field3', label: '字段3', span: 6 }, // 占1/4宽度
{ key: 'field4', label: '字段4', span: 6 }, // 占1/4宽度,满一行
{ key: 'field5', label: '字段5', span: 8 }, // 占1/3宽度
{ key: 'field6', label: '字段6', span: 8 }, // 占1/3宽度
{ key: 'field7', label: '字段7', span: 8 }, // 占1/3宽度,满一行
{ key: 'field8', label: '字段8', span: 12 }, // 占1/2宽度
{ key: 'field9', label: '字段9', span: 12 }, // 占1/2宽度,满一行
{ key: 'description', label: '描述', span: 24 }, // 占满整行
]
<InfoPanel data={data} fields={fields} />
访问完整数据对象
const fields = [
{ key: 'userName', label: '用户名', span: 6 },
{
key: 'status',
label: '状态信息',
span: 18,
// render 函数的第二个参数是完整的数据对象
render: (value, data) => (
<div>
<Tag color={value === 'enabled' ? 'green' : 'default'}>
{value === 'enabled' ? '启用' : '停用'}
</Tag>
<span style={{ marginLeft: 8 }}>
授权终端:{data.grantedTerminals} 台
</span>
</div>
),
},
]
<InfoPanel data={userData} fields={fields} />
自定义网格间距
// 默认间距 [24, 16]
<InfoPanel
data={userData}
fields={userFields}
gutter={[32, 24]} // 更大的间距
/>
// 紧凑布局
<InfoPanel
data={userData}
fields={userFields}
gutter={[16, 12]} // 更小的间距
/>
布局说明
组件使用 Ant Design 的 24 栅格系统:
┌─────────────────────────────────────────────────┐
│ span=6 span=6 span=6 span=6 │ 一行4列
├─────────────────────────────────────────────────┤
│ span=8 span=8 span=8 │ 一行3列
├─────────────────────────────────────────────────┤
│ span=12 span=12 │ 一行2列
├─────────────────────────────────────────────────┤
│ span=24 │ 占满一行
└─────────────────────────────────────────────────┘
常用 span 值:
span=6- 一行 4 列span=8- 一行 3 列span=12- 一行 2 列span=24- 占满整行(适合描述、备注等长文本字段)
样式定制
组件提供以下 CSS 类名供自定义样式:
.info-panel- 组件根容器.info-panel-item- 单个字段容器.info-panel-label- 字段标签.info-panel-value- 字段值.info-panel-actions- 操作按钮区域
使用场景
- 详情页信息展示 - 在详情抽屉或页面中展示对象的属性信息
- 用户信息展示 - 展示用户的基本信息和状态
- 设备信息展示 - 展示设备的配置和参数
- 订单信息展示 - 展示订单的详细信息
- 任何结构化数据展示 - 以标签-值形式展示的数据
注意事项
data为null或undefined时组件不渲染任何内容- 字段
span值总和建议为 24 的倍数以保持布局整齐 - 长文本字段(如描述、备注)建议使用
span=24或span=18 render函数可以返回任何 React 节点,包括组件、文本、HTML 等- 操作按钮会显示在所有字段下方,建议不超过 6 个按钮
- 使用
render函数时,第一个参数是字段值,第二个参数是完整数据对象 - 网格间距
gutter的第一个值是水平间距,第二个值是垂直间距