Ant Design 的封装组件,这个组件不仅继承了 Ant Design 的美观和功能性,还增加了额外的定制性和易用性,使其成为展示详情信息或其他类似数据的完美选择。
GeneralInfo 的优势
高度定制性
GeneralInfo组件提供了丰富的 API,允许开发者根据具体需求定制每一个细节。通过 Property
接口,你可以轻松定义每个属性的标签、获取值的函数、是否显示的条件,以及更多的布局属性。
灵活的数据展示
利用 getValue
函数,开发者可以灵活地定义如何展示数据。这不仅支持直接的数据展示,还可以进行复杂的数据处理,如格式化日期或货币。
易于集成和使用
GeneralInfo 组件设计为易于集成和使用。只需几行代码,你就可以在你的 React 项目中使用它,无论是展示合同信息还是其他任何结构化数据。
相关依赖
React:作为构建用户界面的 JavaScript 库。
Ant Design:一个流行的 React UI 库,提供了丰富的组件和美观的主题。
话不多说,上干货!!!
使用效果:
关于源码:ps 这里使用的是4x版本的react
import React from 'react'
import { Descriptions } from 'antd'
import type { DescriptionsProps } from 'antd/lib/descriptions'
import type { DescriptionsItemProps } from 'antd/lib/descriptions/Item'
import './style.scoped.css'
const { Item } = Descriptions
/**
* @interface Property 属性结构定义
* @property {string} label - 标签
* @property {(item: any) => string | number | React.ReactNode} getValue - 获取值的函数
* @property {(item: any) => boolean} [shouldDisplay] - 是否显示的函数,默认为 true
*/
interface Property {
unit?: string
label: string
getValue: (item: any) => string | number | React.ReactNode
shouldDisplay?: (item: any) => boolean
itemProps?: DescriptionsItemProps
}
/**
* @interface GeneralInfoProps 组件属性接口
* @property {any} dataSource - 数据源对象
* @property {Property[]} properties - 配置项-属性结构数组
* @property {string | React.ReactNode | undefined} [title] - 标题,默认为空字符串
* @property {string | React.ReactNode | undefined} [titleComponent] - 标题组件,默认为空
*/
interface GeneralInfoProps extends Omit<DescriptionsProps, 'title'> {
dataSource: any
styleCSS?: React.CSSProperties
properties: Property[]
title?: string | React.ReactNode
titleComponent?: React.ReactNode
}
/**
* @function GeneralInfo 封装的详情组件
* @param {GeneralInfoProps} props - 组件属性
* @description 封装的详情组件
* @example <GeneralInfo dataSource={dataSource} properties={properties} />
* @returns React.ReactNode
*/
function GeneralInfo({
dataSource,
properties,
title: titleProp,
titleComponent: titleComponentProp,
styleCSS,
children,
...props
}: GeneralInfoProps) {
// 确保至少提供了 title 或 titleComponent
const effectiveTitle = titleComponentProp ?? (
<div className="title-adorn">{titleProp ? titleProp : '默认标题'}</div>
)
return (
<Descriptions
style={styleCSS || { marginLeft: 20 }}
{...props}
title={effectiveTitle}>
{properties.map((property) => {
const item = dataSource // 获取数据源对象
if (!property.shouldDisplay || property.shouldDisplay(item)) {
return (
<Item
{...property?.itemProps}
label={property.label}
key={property.label}>
{property.getValue(item) === 0
? 0
: property.getValue(item) || '-'}
{property.unit && <span> {property.unit}</span>}
</Item>
)
}
return null
})}
{children}
</Descriptions>
)
}
export default GeneralInfo
关于文档:
import React from 'react'
import type { Meta, StoryObj } from '@storybook/react'
import GeneralInfo from '../../components/GeneralInfo'
import type { DescriptionsItemProps } from 'antd/lib/descriptions/Item'
const meta = {
title: '常用详情布局/GeneralInfo',
component: GeneralInfo,
tags: ['autodocs'],
argTypes: {
title: {
description: '标题',
table: {
type: { summary: 'string | ReactNode' }
}
},
titleComponent: {
description: '自定义标题组件',
table: {
type: { summary: 'string | ReactNode' }
}
},
dataSource: {
description: '数据源',
table: {
type: { summary: 'Object' }
}
},
properties: {
description: '配置项',
table: {
type: {
summary:
'{ label:string, getValue:(item)=>string | number | React.ReactNode, unit?:string, shouldDisplay?:(item)=>boolean, itemProps?:DescriptionsItemProps }[]'
}
}
},
styleCSS: {
description: '内联样式',
table: {
type: { summary: 'CSSProperties' }
}
},
children: {
description: '自定义内容',
table: {
type: { summary: 'ReactNode' }
}
}
}
} satisfies Meta<typeof GeneralInfo>
export default meta
type Story = StoryObj<typeof meta>
export const Example: Story = {
args: {
title: '常用信息',
dataSource: {
name: '测试数据',
code: '1212129103243',
city: '浙江省杭州市',
address: '浙江省杭州市西湖区浙大科技园',
type: '2',
status: '待处理',
startDate: '2024-10-21 10:00:00',
endDate: '2025-10-21 10:00:00',
amount: '100856.00',
remark: '备注'
},
properties: [
{
label: '合同名称',
getValue: (item) => item.name,
itemProps: {
labelStyle: {
color: 'red'
}
} as DescriptionsItemProps
},
{
label: '合同编号',
getValue: (item) => item.code
},
{
label: '城市',
getValue: (item) => item.city
},
{
label: '地址',
getValue: (item) => item.address,
shouldDisplay: (item) => item.type === '1'
},
{
label: '类型',
getValue: (item) => item.type
},
{
label: '状态',
getValue: (item) => item.status
},
{
label: '开始日期',
getValue: (item) => item.startDate
},
{
label: '结束日期',
getValue: (item) => item.endDate
},
{
label: '金额',
getValue: (item) => item.amount,
unit: '万元'
},
{
label: '备注',
getValue: (item) => item.remark
}
]
}
}
关于使用:
<GeneralInfo dataSource={dataSource} properties={properties} />