#ProField
This component is an internal component, please do not use it directly.
It is an atomic information component that standardizes field definitions across components such as ProForm, ProTable, ProList, and Filter.
#DEMO
#Issue regression scenarios
字段回归场景
覆盖对象形式 showSearch、受控 TreeSelect、只读空值、数字前后缀及混合 valueEnum。
SearchSelect 回调与远程请求(#9711)
输入关键字时,自定义 onSearch 与 request 会同时收到关键字。
onSearch: (尚未搜索)字段数据流与只读展示(B7–B10)
Search, data flow, and read-only rendering
import {
ProCard,
ProForm,
ProFormDigit,
ProFormSelect,
ProFormTreeSelect,
} from '@ant-design/pro-components';
import { Alert, Space, Typography } from 'antd';
import { useState } from 'react';
const remoteOptions = ['Alpha', 'Beta', 'Gamma', 'Delta'];
export default () => {
const [lastSearch, setLastSearch] = useState('(尚未搜索)');
const [treeOpen, setTreeOpen] = useState(false);
return (
<ProCard direction="column" ghost gutter={[0, 16]}>
<Alert
type="info"
showIcon
message="字段回归场景"
description="覆盖对象形式 showSearch、受控 TreeSelect、只读空值、数字前后缀及混合 valueEnum。"
/>
<ProCard title="SearchSelect 回调与远程请求(#9711)">
<Space direction="vertical" style={{ width: '100%' }}>
<Typography.Text type="secondary">
输入关键字时,自定义 onSearch 与 request 会同时收到关键字。
</Typography.Text>
<ProForm submitter={false}>
<ProFormSelect.SearchSelect
name="keyword"
label="远程搜索"
debounceTime={100}
request={async ({ keyWords }) => {
const keyword = keyWords ?? '';
return remoteOptions
.filter((item) =>
item.toLowerCase().includes(keyword.toLowerCase()),
)
.map((item) => ({ label: item, value: item }));
}}
fieldProps={{
showSearch: {
onSearch: (value) => setLastSearch(value || '(空)'),
},
}}
/>
</ProForm>
<Typography.Text code>onSearch: {lastSearch}</Typography.Text>
</Space>
</ProCard>
<ProCard title="字段数据流与只读展示(B7–B10)">
<ProForm
submitter={false}
initialValues={{ amount: 128, status: 0, category: 'frontend' }}
layout="horizontal"
>
<ProFormDigit
name="amount"
label="带前后缀数字"
fieldProps={{ prefix: '¥', addonAfter: '元' }}
/>
<ProFormSelect
name="status"
label="混合值 valueEnum"
valueEnum={
new Map<string | number, React.ReactNode>([
[0, '未开始'],
['1', '进行中'],
[2, '已完成'],
])
}
/>
<ProFormTreeSelect
name="category"
label="受控 TreeSelect"
fieldProps={{
open: treeOpen,
onOpenChange: setTreeOpen,
treeData: [
{
title: '研发',
value: 'development',
children: [
{ title: '前端', value: 'frontend' },
{ title: '后端', value: 'backend' },
],
},
],
}}
/>
<ProFormDigit
label="只读空值"
name="empty"
readonly
fieldProps={{ addonAfter: '次' }}
/>
</ProForm>
</ProCard>
</ProCard>
);
};
模式:
文本与展示类
数值类
金 额 money¥128,000.00 | 数字 digit1,234,567 |
数字范围 digitRange1,000 ~ 5,000 | 秒格式化 second1天0秒 |
百分比 percent99.50% | 百分比(带颜色) + 15.00% 0.00% - 8.00% |
进度条 progress 75% | 评分 rate |
滑动条 slider60 | |
枚举选择类
选择框 select待处理 | 单选 radio待处理 |
单选按钮 radioButton待处理 | 多选 checkbox 待处理 ,进行中 |
开关 switch打开 | 分段选择 segmented待处理 |
远程选择框 select(request)open | 级联选择 cascader zhejiang ,hangzhou ,xihu |
树形选择 treeSelect前端开发组 | 颜色选择 color |
日期时间类
日期 date2024-01-15 | 日期时间 dateTime2024-01-15 10:30:00 |
周 dateWeek2024-3rd | 月 dateMonth2024-01 |
季度 dateQuarter2024-Q1 | 年 dateYear2024 |
时间 time10:30:00 | 相对时间 fromNow3 years ago |
日期范围类
日期范围 dateRange 2024-01-01 ~ 2024-01-31 | 日期时间范围 dateTimeRange 2024-01-01 09:00:00 ~ 2024-01-31 18:00:00 |
时间范围 timeRange 09:00:00 ~ 18:00:00 | 周范围 dateWeekRange 2024-1st ~ 2024-3rd |
月范围 dateMonthRange 2024-01 ~ 2024-06 | 季度范围 dateQuarterRange 2024-Q1 ~ 2024-Q3 |
年范围 dateYearRange 2023 ~ 2025 | |
代码类
代码块 code | JSON 代码块 jsonCode |
import type { ProFieldFCMode } from '@ant-design/pro-components';
import { ProField } from '@ant-design/pro-components';
import { Descriptions, Segmented, Space } from 'antd';
import dayjs from 'dayjs';
import React, { useState } from 'react';
const DEMO_TIMESTAMP = dayjs('2024-01-15 10:30:00').valueOf();
const statusEnum = {
all: { text: '全部', disabled: true, status: 'Default' },
open: { text: '待处理', status: 'Error' },
closed: { text: '已完成', status: 'Success' },
processing: { text: '进行中', status: 'Processing' },
};
/** 受控 ProField,同时传 text + value 确保 read/edit 模式都有值 */
const DemoField: React.FC<{
initialValue: any;
mode: ProFieldFCMode;
valueType?: any;
[key: string]: any;
}> = ({ initialValue, mode, ...rest }) => {
const [val, setVal] = useState(initialValue);
return (
<ProField text={val} value={val} onChange={setVal} mode={mode} {...rest} />
);
};
const Demo = () => {
const [state, setState] = useState<ProFieldFCMode>('read');
return (
<div
style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 24 }}
>
<div style={{ marginBlockEnd: 16 }}>
<span>模式:</span>
<Segmented
value={state}
onChange={(v) => setState(v as ProFieldFCMode)}
options={[
{ label: '只读 read', value: 'read' },
{ label: '编辑 edit', value: 'edit' },
]}
/>
</div>
<Descriptions column={2} title="文本与展示类">
<Descriptions.Item label="空字符串">
<ProField text="" mode="read" />
</Descriptions.Item>
<Descriptions.Item label="文本 text">
<DemoField
initialValue="用户认证服务"
valueType="text"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="文本域 textarea">
<DemoField
initialValue="核心服务,承载全站用户登录与鉴权,高峰期需要关注性能指标"
valueType="textarea"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="密码 password">
<DemoField
initialValue="pro-components"
valueType="password"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="头像 avatar">
<ProField
text="https://gw.alipayobjects.com/zos/antfincdn/efFD%24IOql2/weixintupian_20170331104822.jpg"
mode="read"
valueType="avatar"
/>
</Descriptions.Item>
<Descriptions.Item label="图片 image">
<DemoField
initialValue="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
valueType="image"
mode={state}
/>
</Descriptions.Item>
</Descriptions>
<Descriptions column={2} title="数值类">
<Descriptions.Item label="金额 money">
<DemoField initialValue={128000} valueType="money" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="数字 digit">
<DemoField initialValue={1234567} valueType="digit" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="数字范围 digitRange">
<DemoField
initialValue={[1000, 5000]}
valueType="digitRange"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="秒格式化 second">
<DemoField initialValue={86400} valueType="second" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="百分比 percent">
<DemoField initialValue={99.5} valueType="percent" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="百分比(带颜色)">
<Space>
<ProField
text={15}
valueType={{ type: 'percent', showSymbol: true, showColor: true }}
mode="read"
/>
<ProField
text={0}
valueType={{ type: 'percent', showSymbol: true, showColor: true }}
mode="read"
/>
<ProField
text={-8}
valueType={{ type: 'percent', showSymbol: true, showColor: true }}
mode="read"
/>
</Space>
</Descriptions.Item>
<Descriptions.Item label="进度条 progress">
<DemoField initialValue={75} valueType="progress" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="评分 rate">
<DemoField initialValue={4} valueType="rate" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="滑动条 slider">
<DemoField initialValue={60} valueType="slider" mode={state} />
</Descriptions.Item>
</Descriptions>
<Descriptions column={2} title="枚举选择类">
<Descriptions.Item label="选择框 select">
<DemoField initialValue="open" mode={state} valueEnum={statusEnum} />
</Descriptions.Item>
<Descriptions.Item label="单选 radio">
<DemoField
initialValue="open"
mode={state}
valueType="radio"
valueEnum={statusEnum}
/>
</Descriptions.Item>
<Descriptions.Item label="单选按钮 radioButton">
<DemoField
initialValue="open"
mode={state}
valueType="radioButton"
valueEnum={statusEnum}
/>
</Descriptions.Item>
<Descriptions.Item label="多选 checkbox">
<DemoField
initialValue={['open', 'processing']}
mode={state}
valueType="checkbox"
valueEnum={statusEnum}
/>
</Descriptions.Item>
<Descriptions.Item label="开关 switch">
<DemoField initialValue={true} mode={state} valueType="switch" />
</Descriptions.Item>
<Descriptions.Item label="分段选择 segmented">
<DemoField
initialValue="open"
mode={state}
valueType="segmented"
valueEnum={statusEnum}
/>
</Descriptions.Item>
<Descriptions.Item label="远程选择框 select(request)">
<DemoField
initialValue="open"
mode={state}
valueType="select"
request={async () => [
{ label: '全部', value: 'all' },
{ label: '待处理', value: 'open' },
{ label: '已完成', value: 'closed' },
{ label: '进行中', value: 'processing' },
]}
/>
</Descriptions.Item>
<Descriptions.Item label="级联选择 cascader">
<DemoField
initialValue={['zhejiang', 'hangzhou', 'xihu']}
mode={state}
valueType="cascader"
fieldProps={{
fieldNames: { label: 'name' },
}}
request={async () => [
{
value: 'zhejiang',
name: '浙江省',
children: [
{
value: 'hangzhou',
name: '杭州市',
children: [{ value: 'xihu', name: '西湖区' }],
},
],
},
{
value: 'jiangsu',
name: '江苏省',
children: [
{
value: 'nanjing',
name: '南京市',
children: [{ value: 'gulou', name: '鼓楼区' }],
},
],
},
]}
/>
</Descriptions.Item>
<Descriptions.Item label="树形选择 treeSelect">
<DemoField
initialValue="tech-fe"
mode={state}
valueType="treeSelect"
fieldProps={{
options: [
{
label: '技术研发部',
value: 'tech',
children: [
{ label: '前端开发组', value: 'tech-fe' },
{ label: '后端开发组', value: 'tech-be' },
],
},
{
label: '产品设计部',
value: 'product',
children: [
{ label: '产品策划组', value: 'product-pm' },
{ label: 'UX 设计组', value: 'product-ux' },
],
},
],
}}
/>
</Descriptions.Item>
<Descriptions.Item label="颜色选择 color">
<DemoField initialValue="#1677FF" mode={state} valueType="color" />
</Descriptions.Item>
</Descriptions>
<Descriptions column={2} title="日期时间类">
<Descriptions.Item label="日期 date">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="date"
/>
</Descriptions.Item>
<Descriptions.Item label="日期时间 dateTime">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="dateTime"
/>
</Descriptions.Item>
<Descriptions.Item label="周 dateWeek">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="dateWeek"
/>
</Descriptions.Item>
<Descriptions.Item label="月 dateMonth">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="dateMonth"
/>
</Descriptions.Item>
<Descriptions.Item label="季度 dateQuarter">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="dateQuarter"
/>
</Descriptions.Item>
<Descriptions.Item label="年 dateYear">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="dateYear"
/>
</Descriptions.Item>
<Descriptions.Item label="时间 time">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="time"
/>
</Descriptions.Item>
<Descriptions.Item label="相对时间 fromNow">
<DemoField
initialValue={DEMO_TIMESTAMP}
mode={state}
valueType="fromNow"
/>
</Descriptions.Item>
</Descriptions>
<Descriptions column={2} title="日期范围类">
<Descriptions.Item label="日期范围 dateRange">
<DemoField
initialValue={[
dayjs('2024-01-01').valueOf(),
dayjs('2024-01-31').valueOf(),
]}
mode={state}
valueType="dateRange"
/>
</Descriptions.Item>
<Descriptions.Item label="日期时间范围 dateTimeRange">
<DemoField
initialValue={[
dayjs('2024-01-01 09:00:00').valueOf(),
dayjs('2024-01-31 18:00:00').valueOf(),
]}
mode={state}
valueType="dateTimeRange"
/>
</Descriptions.Item>
<Descriptions.Item label="时间范围 timeRange">
<DemoField
initialValue={[
dayjs('2024-01-01 09:00:00').valueOf(),
dayjs('2024-01-01 18:00:00').valueOf(),
]}
mode={state}
valueType="timeRange"
/>
</Descriptions.Item>
<Descriptions.Item label="周范围 dateWeekRange">
<DemoField
initialValue={[
dayjs('2024-01-01').valueOf(),
dayjs('2024-01-14').valueOf(),
]}
mode={state}
valueType="dateWeekRange"
/>
</Descriptions.Item>
<Descriptions.Item label="月范围 dateMonthRange">
<DemoField
initialValue={[
dayjs('2024-01-01').valueOf(),
dayjs('2024-06-30').valueOf(),
]}
mode={state}
valueType="dateMonthRange"
/>
</Descriptions.Item>
<Descriptions.Item label="季度范围 dateQuarterRange">
<DemoField
initialValue={[
dayjs('2024-01-01').valueOf(),
dayjs('2024-09-30').valueOf(),
]}
mode={state}
valueType="dateQuarterRange"
/>
</Descriptions.Item>
<Descriptions.Item label="年范围 dateYearRange">
<DemoField
initialValue={[
dayjs('2023-01-01').valueOf(),
dayjs('2025-12-31').valueOf(),
]}
mode={state}
valueType="dateYearRange"
/>
</Descriptions.Item>
</Descriptions>
<Descriptions column={2} title="代码类">
<Descriptions.Item label="代码块 code">
<DemoField
initialValue={`pnpm install
pnpm run build
pnpm run deploy --env production`}
mode={state}
valueType="code"
/>
</Descriptions.Item>
<Descriptions.Item label="JSON 代码块 jsonCode">
<DemoField
initialValue={`{
"service": "user-auth",
"port": 8080,
"replicas": 3
}`}
mode={state}
valueType="jsonCode"
/>
</Descriptions.Item>
</Descriptions>
</div>
);
};
export default () => (
<div style={{ padding: 24 }}>
<Demo />
</div>
);
空字符串- | 头像 |
文本 | 颜色 |
颜色禁用 | 图片 |
金额 | 数字 |
数字范围 | 秒格式化 |
百分比 | 评分 |
slider | 选择框 请选择 |
多选 | 多选 labelInValue |
单选 | 单选按钮 |
远程选择框 请选择 | 远程级联框 请选择 |
进度条 | 进度条 |
进度条 | 百分比空值- |
百分比 10.00% 0.00% - 10.00% | 日期时间 |
相对于当前时间 | 日期 |
日期区间 | 日期时间区间 |
时间 | 时间区间 |
密码 | 代码块 |
JSON 代码块 | |
ProField 基础测试 Props 说明:
- text: 显示的文本内容
- mode: 显示模式,'read' 表示只读,'edit' 表示编辑
- valueType: 值类型,决定如何渲染内容
- fieldProps: 字段属性配置
- disabled: 是否禁用
Radio.Group 配置:
- onChange: 值变化回调函数
- value: 当前选中的值
- 模式切换: 用于切换 ProField 的显示模式
Switch 配置:
- checked: 是否选中
- onChange: 值变化回调函数
- 简约模式: 控制是否使用简约模式
Descriptions 配置:
- column: 列数配置
- 内容展示: 用于展示各种 ProField 组件
支持的 valueType 类型:
- text: 文本类型
- avatar: 头像类型
- color: 颜色类型
- image: 图片类型
- money: 金额类型
- digit: 数字类型
- date: 日期类型
- dateRange: 日期区间类型
- dateTimeRange: 日期时间区间类型
- time: 时间类型
- timeRange: 时间区间类型
- password: 密码类型
- code: 代码块类型
- jsonCode: JSON 代码块类型
fieldProps 配置:
- disabled: 是否禁用字段
- precision: 数字精度
- style: 样式配置
- customSymbol: 自定义货币符号
- width: 图片宽度
显示模式特点:
- 只读模式: 仅显示内容,不可编辑
- 编辑模式: 可以编辑内容
- 简约模式: 使用简约的显示样式
- 动态切换: 支持动态切换显示模式
布局特点:
- 控制区域: 顶部显示模式切换控制
- 展示区域: 使用 Descriptions 展示各种字段类型
- 响应式设计: 自动适配不同屏幕尺寸
- 网格 布局: 使用网格布局展示多个字段
使用场景:
- 字段测试: 测试各种字段类型的显示效果
- 模式切换: 测试只读和编辑模式的切换
- 样式测试: 测试简约模式和普通模式的样式差异
- 功能验证: 验证各种字段类型的功能
最佳实践:
- 类型选择: 根据数据类型选择合适的 valueType
- 模式设计: 合理设计只读和编辑模式
- 样式配置: 根据需求配置合适的样式
- 用户体验: 提供清晰的模式切换和内容展示
import type { ProFieldFCMode } from '@ant-design/pro-components';
import { ProField } from '@ant-design/pro-components';
import { Descriptions, Radio, Space } from 'antd';
import dayjs from 'dayjs';
import { useState } from 'react';
const Demo = () => {
const [state, setState] = useState<ProFieldFCMode>('edit');
return (
<>
<Space>
<Radio.Group
onChange={(e) => setState(e.target.value as ProFieldFCMode)}
value={state}
>
<Radio value="read">只读</Radio>
<Radio value="edit">编辑</Radio>
</Radio.Group>
</Space>
<br />
<br />
<Descriptions column={2}>
<Descriptions.Item label="空字符串">
<ProField text="" mode="read" />
</Descriptions.Item>
<Descriptions.Item label="头像">
<ProField
text="https://avatars2.githubusercontent.com/u/8186664?s=60&v=4"
mode="read"
valueType="avatar"
/>
</Descriptions.Item>
<Descriptions.Item label="文本">
<ProField
text="这是一段文本"
fieldProps={{
disabled: true,
}}
valueType="text"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="颜色">
<ProField text="blue" valueType="color" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="颜色禁用">
<ProField
text="blue"
valueType="color"
fieldProps={{
disabled: true,
}}
mode={state}
/>
<ProField text="blue" valueType="color" disabled mode="read" />
</Descriptions.Item>
<Descriptions.Item label="图片">
<ProField
text="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
valueType={{
type: 'image',
width: 100,
}}
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="金额">
<ProField
numberPopoverRender
fieldProps={{
precision: 2,
style: {
width: 200,
},
}}
text="10000"
valueType="money"
mode={state}
/>
<ProField
valueType="money"
label="自定义货币符号"
name="amount4"
fieldProps={{
value: 2221212.22,
customSymbol: '💰',
}}
mode="read"
/>
</Descriptions.Item>
<Descriptions.Item label="数字">
<ProField
text="19897979797979"
valueType="digit"
fieldProps={{
min: 1,
max: 10000,
precision: 0,
formatter: null,
}}
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="数字范围">
<ProField text={[123, 456]} valueType="digitRange" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="秒格式化">
<ProField text={2000000} valueType="second" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="百分比">
<ProField text="100" valueType="percent" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="评分">
<ProField text={3.5} valueType="rate" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="slider">
<ProField text="40" valueType="slider" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="选择框">
<ProField
text="open"
mode={state}
valueEnum={{
all: { text: '全部', disabled: true, status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
}}
/>
</Descriptions.Item>
<Descriptions.Item label="多选">
<ProField
text={['open', 'closed']}
mode={state}
valueType="checkbox"
valueEnum={{
all: { text: '全部', disabled: true, status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
}}
/>
</Descriptions.Item>
<Descriptions.Item label="多选 labelInValue">
<ProField
text={[
{
value: 'open1',
label: '打开',
},
{
value: 'closed2',
label: '关闭',
},
]}
mode={state}
valueType="checkbox"
valueEnum={{
all: { text: '全部', disabled: true, status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
}}
/>
</Descriptions.Item>
<Descriptions.Item label="单选">
<ProField
text="open"
mode={state}
valueType="radio"
fieldProps={{
layout: 'horizontal',
}}
valueEnum={{
all: { text: '全部', disabled: true, status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
}}
/>
</Descriptions.Item>
<Descriptions.Item label="单选按钮">
<ProField
text="open"
mode={state}
valueType="radioButton"
valueEnum={{
all: { text: '全部', disabled: true, status: 'Default' },
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
}}
/>
</Descriptions.Item>
<Descriptions.Item label="远程选择框">
<ProField
text="open"
mode={state}
params={{
name: 'test',
}}
valueType="select"
request={async () => {
return [
{ label: '全部', value: 'all' },
{ label: '未解决', value: 'open' },
{ label: '已解决', value: 'closed' },
{ label: '解决中', value: 'processing' },
{
label: '特殊选项',
value: 'optGroup',
optionType: 'optGroup',
options: [
{ label: '不解决', value: 'no' },
{ label: '已废弃', value: 'clear' },
],
},
];
}}
/>
</Descriptions.Item>
<Descriptions.Item label="远程级联框">
<ProField
mode={state}
params={{
name: 'test',
}}
valueType="cascader"
request={async () => {
return [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
];
}}
/>
</Descriptions.Item>
<Descriptions.Item label="进度条">
<ProField text="40" valueType="progress" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="进度条">
<ProField text="40%" valueType="progress" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="进度条">
<ProField text="love" valueType="progress" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="百分比空值">
<ProField valueType="percent" mode="read" />
</Descriptions.Item>
<Descriptions.Item label="百分比">
<Space>
<ProField
text={10}
valueType={{
type: 'percent',
showSymbol: (text: number) => {
if (text < 0) {
return true;
}
return false;
},
showColor: true,
}}
mode="read"
/>
<ProField
text={0}
valueType={{
type: 'percent',
showSymbol: true,
showColor: true,
}}
mode="read"
/>
<ProField
text={-10}
valueType={{
type: 'percent',
showSymbol: true,
showColor: true,
}}
mode="read"
/>
</Space>
</Descriptions.Item>
<Descriptions.Item label="日期时间">
<ProField
text={dayjs('2019-11-16 12:50:26').valueOf()}
valueType="dateTime"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="相对于当前时间">
<Space>
<ProField
text={dayjs('2019-11-16 12:50:26').valueOf()}
valueType="fromNow"
mode={state}
/>
<ProField
text={dayjs('2020-11-16 12:50:26').valueOf()}
valueType="fromNow"
mode={state}
/>
</Space>
</Descriptions.Item>
<Descriptions.Item label="日期">
<ProField
text={dayjs('2019-11-16 12:50:26').valueOf()}
valueType="date"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="日期区间">
<ProField
text={[
dayjs('2019-11-16 12:50:26').add(-1, 'd').valueOf(),
dayjs('2019-11-16 12:50:26').valueOf(),
]}
valueType="dateRange"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="日期时间区间">
<ProField
text={[
dayjs('2019-11-16 12:50:26').add(-1, 'd').valueOf(),
dayjs('2019-11-16 12:50:26').valueOf(),
]}
valueType="dateTimeRange"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="时间">
<ProField
text={dayjs('2019-11-16 12:50:26').valueOf()}
valueType="time"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="时间区间">
<ProField
text={[
dayjs('2019-11-16 12:50:26').add(-1, 'd').valueOf(),
dayjs('2019-11-16 12:50:26').valueOf(),
]}
valueType="timeRange"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="密码">
<ProField text="password" valueType="password" mode={state} />
</Descriptions.Item>
<Descriptions.Item label="代码块">
<ProField
text={`
yarn run v1.22.0
$ eslint --format=pretty ./packages
Done in 9.70s.
`}
valueType="code"
mode={state}
/>
</Descriptions.Item>
<Descriptions.Item label="JSON 代码块">
<ProField
text={`{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"jsx": "preserve",
"esModuleInterop": true,
"experimentalDecorators": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"declaration": true,
"skipLibCheck": true
},
"include": ["**/src", "**/docs", "scripts", "**/demo", ".eslintrc.js"]
}
`}
valueType="jsonCode"
mode={state}
/>
</Descriptions.Item>
</Descriptions>
<div
style={{
marginTop: '20px',
padding: '20px',
backgroundColor: '#f5f5f5',
borderRadius: '6px',
}}
>
<h4>ProField 基础测试 Props 说明:</h4>
<ul>
<li>
<strong>text</strong>: 显示的文本内容
</li>
<li>
<strong>mode</strong>: 显示模式,'read' 表示只读,'edit' 表示编辑
</li>
<li>
<strong>valueType</strong>: 值类型,决定如何渲染内容
</li>
<li>
<strong>fieldProps</strong>: 字段属性配置
</li>
<li>
<strong>disabled</strong>: 是否禁用
</li>
</ul>
<h4>Radio.Group 配置:</h4>
<ul>
<li>
<strong>onChange</strong>: 值变化回调函数
</li>
<li>
<strong>value</strong>: 当前选中的值
</li>
<li>
<strong>模式切换</strong>: 用于切换 ProField 的显示模式
</li>
</ul>
<h4>Switch 配置:</h4>
<ul>
<li>
<strong>checked</strong>: 是否选中
</li>
<li>
<strong>onChange</strong>: 值变化回调函数
</li>
<li>
<strong>简约模式</strong>: 控制是否使用简约模式
</li>
</ul>
<h4>Descriptions 配置:</h4>
<ul>
<li>
<strong>column</strong>: 列数配置
</li>
<li>
<strong>内容展示</strong>: 用于展示各种 ProField 组件
</li>
</ul>
<h4>支持的 valueType 类型:</h4>
<ul>
<li>
<strong>text</strong>: 文本类型
</li>
<li>
<strong>avatar</strong>: 头像类型
</li>
<li>
<strong>color</strong>: 颜色类型
</li>
<li>
<strong>image</strong>: 图片类型
</li>
<li>
<strong>money</strong>: 金额类型
</li>
<li>
<strong>digit</strong>: 数字类型
</li>
<li>
<strong>date</strong>: 日期类型
</li>
<li>
<strong>dateRange</strong>: 日期区间类型
</li>
<li>
<strong>dateTimeRange</strong>: 日期时间区间类型
</li>
<li>
<strong>time</strong>: 时间类型
</li>
<li>
<strong>timeRange</strong>: 时间区间类型
</li>
<li>
<strong>password</strong>: 密码类型
</li>
<li>
<strong>code</strong>: 代码块类型
</li>
<li>
<strong>jsonCode</strong>: JSON 代码块类型
</li>
</ul>
<h4>fieldProps 配置:</h4>
<ul>
<li>
<strong>disabled</strong>: 是否禁用字段
</li>
<li>
<strong>precision</strong>: 数字精度
</li>
<li>
<strong>style</strong>: 样式配置
</li>
<li>
<strong>customSymbol</strong>: 自定义货币符号
</li>
<li>
<strong>width</strong>: 图片宽度
</li>
</ul>
<h4>显示模式特点:</h4>
<ul>
<li>
<strong>只读模式</strong>: 仅显示内容,不可编辑
</li>
<li>
<strong>编辑模式</strong>: 可以编辑内容
</li>
<li>
<strong>简约模式</strong>: 使用简约的显示样式
</li>
<li>
<strong>动态切换</strong>: 支持动态切换显示模式
</li>
</ul>
<h4>布局特点:</h4>
<ul>
<li>
<strong>控制区域</strong>: 顶部显示模式切换控制
</li>
<li>
<strong>展示区域</strong>: 使用 Descriptions 展示各种字段类型
</li>
<li>
<strong>响应式设计</strong>: 自动适配不同屏幕尺寸
</li>
<li>
<strong>网格布局</strong>: 使用网格布局展示多个字段
</li>
</ul>
<h4>使用场景:</h4>
<ul>
<li>
<strong>字段测试</strong>: 测试各种字段类型的显示效果
</li>
<li>
<strong>模式切换</strong>: 测试只读和编辑模式的切换
</li>
<li>
<strong>样式测试</strong>: 测试简约模式和普通模式的样式差异
</li>
<li>
<strong>功能验证</strong>: 验证各种字段类型的功能
</li>
</ul>
<h4>最佳实践:</h4>
<ul>
<li>
<strong>类型选择</strong>: 根据数据类型选择合适的 valueType
</li>
<li>
<strong>模式设计</strong>: 合理设计只读和编辑模式
</li>
<li>
<strong>样式配置</strong>: 根据需求配置合适的样式
</li>
<li>
<strong>用户体验</strong>: 提供清晰的模式切换和内容展示
</li>
</ul>
</div>
</>
);
};
export default () => (
<div style={{ padding: 24 }}>
<Demo />
</div>
);
常用关键字:lca
import { ProForm, ProFormSelect } from '@ant-design/pro-components';
import { useState } from 'react';
export function App() {
const [searchValue, setSearchValue] = useState('');
const [selectOpen, setSelectOpen] = useState(false);
function onBlur() {
setSelectOpen(false);
}
function onFocus() {
setSelectOpen(true);
}
/** 点击常用关键字的字母 */
function onClick(e: any) {
const text = e.target as HTMLSpanElement;
// 更改搜索框文字
setSearchValue(text.innerText);
onFocus();
}
/** 下拉搜索 */
function onSearch(value: string) {
setSearchValue(value);
}
/** 下拉选中 */
function onSelect() {
onBlur();
}
return (
<div>
<ProForm>
<ProFormSelect
name="name"
placeholder="请输入搜索关键字"
allowClear
width={330}
secondary
options={
[
{
v: 'v1',
l: 'l1',
},
{
v: 'v2',
l: 'l3',
},
{
v: 'v4',
l: 'l5',
},
] as any
}
fieldProps={{
fieldNames: {
value: 'v',
label: 'l',
options: 'options',
},
suffixIcon: null,
showSearch: true, // 使单选模式可搜索
popupMatchSelectWidth: false,
optionFilterProp: 'label', // 搜索时过滤对应的 option 属性
optionLabelProp: 'label', // 回填到选择框的 Option 的属性值
searchValue,
open: selectOpen,
onBlur: () => onBlur(),
onFocus: () => onFocus(),
onSearch: (val) => onSearch(val),
onSelect: () => onSelect(),
}}
/>
</ProForm>
<div className="keys">
<b>常用关键字:</b>
{['l', 'c', 'a'].map((item) => {
return (
<span
key={item}
onClick={onClick}
style={{
marginInlineStart: 8,
cursor: 'pointer',
}}
>
{item}
</span>
);
})}
</div>
</div>
);
}
export default () => (
<div style={{ padding: 24 }}>
<App />
</div>
);
ProFormSelect 搜索值自动清除 Props 说明:
- name: 字段名
- placeholder: 占位符文本
- allowClear: 是否允许清除
- width: 控件宽度
- secondary: 是否使用次要样式
- mode: 选择模式,'tags' 表示标签模式
- options: 选项数组
- fieldProps: 字段属性配置
fieldProps 配置:
- fieldNames: 字段名映射配置
- showSearch: 是否显示搜索功能
- autoClearSearchValue: 是否自动清除搜索值
fieldNames 配置:
- value: 值字段名
- label: 标签字段名
- options: 选项字段名
- 字段映射: 将自定义字段名映射为标准字段名
选项配置:
- v: 选项值
- l: 选项标签
- 自定义字段: 使用自定义字段名结构
搜索功能特点:
- 搜索输入: 支持输入关键字进行搜索
- 自动清除: 选择后自动清除搜索框的值
- 标签模式: 支持多选标签模式
- 字段映射: 支持自定义字段名映射
布局特点:
- 固定宽度: 使用固定宽度 330px
- 次要样式: 使用次要样式显示
- 响应式设计: 自动适配不同屏幕尺寸
- 清晰布局: 提供清晰的输入和选择界面
使用场景:
- 多选搜索: 需要多选和搜索功能的场景
- 自定义字段: 使用自定义字段名结构的场景
- 自动清除: 需要选择后自动清除搜索值的场景
- 标签选择: 需要标签形式多选的场景
最佳实践:
- 字段映射: 合理配置字段名映射关系
