主题
Ant Design
介绍
Ant Design 是一个企业级 UI 设计语言和 React 实现,提供了一套高质量的 React 组件库。
Button
Icon 常见组合
tsx
<Button type="primary" icon={<SearchOutlined />}>
查询
</Button>
<Button icon={<ReloadOutlined />}>
重置
</Button>
<Button type="primary" icon={<PlusOutlined />}>
新增
</Button>
<Button type="primary" icon={<UploadOutlined />}>
导入
</Button>
<Button type="primary" icon={<DownloadOutlined />}>
导出
</Button>Table
基本使用
tsx
<Table columns={tableColumns} dataSource={tableData} rowKey="gid" pagination={false} size="small" bordered />defaultExpandAllRows 失效
设定一个 key 值,key 值一旦改变会自动变成新的组件:
tsx
<Table key={key} defaultExpandAllRows>columns.width 不生效
为 scroll 指定宽度:
tsx
<Table
columns={tableColumns}
dataSource={tableData}
rowKey="gid"
pagination={false}
size="small"
scroll={{
// x: '100%',
x: tableColumns.reduce((a, b) => a + (b.width || 0), 0),
}}
/>rowKey
js
// 比如你的数据主键是 uid
return <Table rowKey="uid" />
// 或
return <Table rowKey={(record) => record.uid} />
// 延申:多个id
return <Table rowKey={(record) => `${record.uid}_${record.pid}`} />expandable
expandable.expandedRowKeys 与 rowkey 进行绑定。
preserveSelectedRowKeys:值为 true 时支持跨页勾选。
Form
获取表单实例
tsx
const App = () => {
const [form] = Form.useForm()
return <Form ref={form}></Form>
}
// 或者
const App = () => {
const formRef = React.useRef()
return <Form ref={formRef}></Form>
}tsx
class App extends React.Component {
formRef = React.createRef()
render() {
return <Form ref={this.formRef}></Form>
}
}常见属性
样式类
colon:显示 label 后面的冒号。(只有在属性layout为horizontal时有效)labelAlign:label 标签的文本对齐方式labelWrap:label 标签的文本换行方式labelCol:label 标签布局,同<Col>组件wrapperCol:输入控件设置布局样式requiredMark:必选样式size:设置字段组件的尺寸(仅限 antd 组件)disabled:设置表单组件禁用
常用事件
onValuesChange: (changedValues, allValues) => void:字段值更新时触发回调事件。onFieldsChange: (changedFields, allFields) => void:字段更新时触发回调事件。
Form.Item
常见属性
- label
- name
- colon
- extra
- hidden
- required
- tooltip
- labelAlign
- labelCol
- wrapperCol
常见事件
- valuePropName:兼容非 value 的字段。
- getValueFromEvent:把 Select 的 onChange 参数(数组)转换为你要保存的字符串 "1,2,3" 并返回给 Form。
- getValueProps:把表单里保存的字符串转换为 Select 需要的 value(数组),用于回显。
自定义表单组件
核心:实现 value、onChange 逻辑
TreeSelect
tsx
const App = () => {
const [value, setValue] = useState<string | undefined>()
return (
<TreeSelect
style={{ width: '100%' }}
treeData={[]}
value={value}
onChange={(val) => {
setValue(val)
}}
showSearch
treeNodeFilterProp="title"
dropdownStyle={{ maxHeight: 400, overflow: 'auto', maxWidth: 500 }}
dropdownMatchSelectWidth={false}
allowClear
placeholder={`请选择`}
/>
)
}DatePicker
RangePicker
tsx
const App = () => {
const [value, setValue] = useState<string[]>([])
return (
<DatePicker.RangePicker
style={{ width: '100%' }}
value={value ? [value[0] !== '' ? moment(value[0]) : '', value[1] !== '' ? moment(value[1]) : ''] : null}
onChange={(val, dateStr) => {
setValue(dateStr)
}}
format={DATA_FORMAT}
allowClear
/>
)
}Input
核心 props
value: string:输入框的值onChange: (e: string) => void:值变化时的回调。通过e.target.value获取输入框的值。
InputNumber
核心 props
value: number:输入框的值。onChange: (value: number | null) => void:值变化时的回调。value是当前输入的值。min:最小值max:最大值precision:数值精度,配置formatter时会以formatter为准formatter: function(value: number | string, info: { userTyping: boolean, input: string }): string:指定输入框展示值的格式
Select
核心 props
value: string | number:选择框的值。onChange: (value: string | number, option: any) => void:值变化时的回调。value是选中的值,option是选中的选项。
多选:
mode="multiple"maxTagCount={3}
TreeSelect
核心 props
value: string | string[]:选中项的值。onChange: (value: string | string[], labelList: ReactNode[], extra: any) => void:值变化时的回调。value是选中的值,labelList是选中项的标签列表。
Checkbox
核心 props
checked: boolean:是否选中。onChange: (e: CheckboxChangeEvent) => void:状态变化时的回调。通过e.target.checked获取选中状态。
Checkbox.Group
核心 props
value: string[]:选中项的值数组。onChange: (checkedValue: string[]) => void:选中项变化时的回调。
Radio
核心 props
checked: boolean:是否选中。onChange: (e: RadioChangeEvent) => void:状态变化时的回调。通过e.target.checked获取选中状态。
Radio.Group
核心 props
value: string | number:选中的值。onChange: (e: RadioChangeEvent) => void:选中项变化时的回调。通过e.target.value获取选中的值。
DatePicker
核心 props
value: moment.Moment:选中的日期。onChange: (date: moment.Moment | null, dateString: string) => void:值变化时的回调。date是选中的日期对象,dateString是格式化后的日期字符串。
Upload
核心 props
fileList: UploadFile[]:当前的文件列表。beforeUpload: (file, fileList) => boolean | Promise<File> | Upload.LIST_IGNORE:上传文件之前的钩子,参数为上传的文件,若返回false则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入 File 或 Blob 对象则上传 resolve 传入对象);也可以返回Upload.LIST_IGNORE,此时列表中将不展示此文件。onChange: (info: { file: UploadFile; fileList: UploadFile[] }) => void:文件列表变化时的回调。info.file是当前操作的文件,info.fileList是最新的文件列表。
配合 Form.Item 使用
tsx
const getValueFromEvent = (info: UploadChangeParam<UploadFile<any>>) => {
const fileList = info.fileList || []
// 只把已经从后端拿到 id 的文件记录到表单(避免保存临时 uid)
const ids = fileList
.map((f) => {
// 后端返回的 id 假定在 f.response.id
const resp = (f.response || {}) as { id?: string }
return resp.id ? String(resp.id) : undefined
})
.filter(Boolean) as string[]
return ids.join(',')
}
const getValueProps = (value?: string) => {
if (!value) {
return { fileList: [] }
}
const ids = String(value)
.split(',')
.map((s) => s.trim())
.filter(Boolean)
const fileList: UploadFile[] = ids.map((id) => ({
uid: id,
name: `file-${id}`,
status: 'done',
url: `http://example.com/file/${id}`,
// 自定义字段以备后用
id,
}))
return { fileList }
}
return () => (
<Form.Item
label="上传文件(保存为 id 字符串)"
name="fileUrl"
// 告诉 Form 把这个字段当作 child 的 fileList prop
valuePropName="fileList"
// 当 Upload 的 onChange 被触发(参数通常是 info),把 info.fileList 转换为要保存的字符串
getValueFromEvent={getValueFromEvent}
// 当表单值变化(或者有 initialValues / setFieldsValue)时,把表单里保存的字符串转换成 child 需要的 fileList
getValueProps={getValueProps}
>
<Upload beforeUpload={() => false}>
<Button icon={<PlusOutlined />}>上传文件</Button>
</Upload>
</Form.Item>
)Modal
tsx
const App = () => {
const [vis, setVis] = useState(false)
return (
<>
<Button type="primary" onClick={() => setVis(true)}>
打开 Modal
</Button>
<Modal
open={vis}
title="内容"
footer={null}
onCancel={() => {
setVis(false)
}}
keyboard={false}
maskClosable={false}
>
内容
</Modal>
</>
)
}Drawer
tsx
const App = () => {
const [vis, setVis] = useState(false)
return (
<>
<Button type="primary" onClick={() => setVis(true)}>
打开 Drawer
</Button>
<Drawer
open={titleDrawerVis}
width="40vw"
title="标题栏"
onClose={() => {
setVis(false)
}}
keyboard={false}
maskClosable={false}
>
内容
</Drawer>
</>
)
}