返回文章
Ant Design 实战经验 — 从配置到最佳实践
4 分钟阅读Ant DesignReact前端工程化UI组件库
前言
Ant Design 是国内最流行的 React UI 组件库之一。本文总结在实际项目中深度使用 Ant Design 的经验和最佳实践。
主题定制
Ant Design 5.x 引入了基于 CSS-in-JS 的 token 主题系统,定制主题变得前所未有的简单:
import { ConfigProvider } from "antd";
const theme = {
token: {
colorPrimary: "#6366f1",
borderRadius: 8,
colorBgContainer: "#ffffff",
fontFamily: "DM Sans, sans-serif",
},
components: {
Button: {
borderRadiusLG: 6,
controlHeightLG: 48,
},
Card: {
paddingLG: 24,
},
},
};
export default function App({ children }) {
return (
<ConfigProvider theme={theme}>
{children}
</ConfigProvider>
);
}暗色模式适配
配合 useTheme 可以动态切换主题:
function ThemeWrapper({ children }) {
const [isDark, setIsDark] = useState(false);
return (
<ConfigProvider
theme={{
algorithm: isDark ? theme.darkAlgorithm : theme.defaultAlgorithm,
token: { colorPrimary: "#6366f1" },
}}
>
<Switch onChange={(v) => setIsDark(v)} />
{children}
</ConfigProvider>
);
}Form 表单最佳实践
模态框中的 Form
在 Modal 中使用 Form 时,使用 destroyOnClose 避免表单状态污染:
function CreateUserModal({ open, onClose }) {
const [form] = Form.useForm();
return (
<Modal
open={open}
onOk={() => form.submit()}
onCancel={() => { form.resetFields(); onClose(); }}
destroyOnClose
>
<Form form={form} layout="vertical" onFinish={handleSubmit}>
<Form.Item name="name" label="姓名" rules={[{ required: true }]}>
<Input />
</Form.Item>
</Form>
</Modal>
);
}表单联动
<Form.Item name="country" label="国家">
<Select onChange={() => form.setFieldValue("city", undefined)} />
</Form.Item>
<Form.Item
name="city"
label="城市"
dependencies={["country"]}
rules={[{ required: true, message: "请选择城市" }]}
>
<Select options={cities[form.getFieldValue("country")] || []} />
</Form.Item>Table 性能优化
处理大量数据时,Table 的性能是关键:
| 优化手段 | 说明 | 效果 |
|---|---|---|
virtual |
虚拟滚动(5.x+) | 万级数据流畅渲染 |
scroll={{ y: 480 }} |
固定高度避免全量渲染 | 大幅减少 DOM 节点 |
onChange + 分页 |
服务端分页 | 每次只加载当前页 |
shouldCellUpdate |
控制单元格重渲染 | 减少不必要更新 |
<Table
columns={columns}
dataSource={data}
scroll={{ y: 480, x: 1200 }}
pagination={{ pageSize: 50, showSizeChanger: true }}
virtual={data.length > 1000}
onChange={(pagination) => fetchData(pagination)}
/>布局模式
ProLayout
对于中后台项目,ProLayout 提供了开箱即用的布局方案:
import ProLayout from "@ant-design/pro-layout";
export default function AdminLayout() {
return (
<ProLayout
title="后台管理"
logo="/logo.svg"
layout="mix"
splitMenus
menuRender={(props, defaultDom) => (
<Menu {...props} />
)}
>
<Outlet />
</ProLayout>
);
}响应式栅格
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} lg={8} xl={6}>
<Card>卡片 1</Card>
</Col>
</Row>国际化
import { ConfigProvider } from "antd";
import zhCN from "antd/locale/zh_CN";
<ConfigProvider locale={zhCN}>
<App />
</ConfigProvider>Table + Form 筛选组合
function UserList() {
const [params, setParams] = useState({});
const { data, loading } = useFetch("/api/users", params);
return (
<Card>
<Form layout="inline" onFinish={(v) => setParams(v)}>
<Form.Item name="keyword"><Input.Search placeholder="搜索" /></Form.Item>
<Form.Item name="status">
<Select placeholder="状态" options={statusOptions} allowClear />
</Form.Item>
<Form.Item>
<Space>
<Button type="primary" htmlType="submit">查询</Button>
<Button htmlType="reset">重置</Button>
</Space>
</Form.Item>
</Form>
<Table
columns={columns}
dataSource={data?.list}
loading={loading}
pagination={{ total: data?.total }}
/>
</Card>
);
}常见坑点
- Modal 中 Table 固定列 — 需要给 Modal 设置
width,否则固定列计算可能出错 - Select 搜索 — 大数据量用
showSearch+filterOption,上万条考虑virtual - DatePicker 值类型 —
dayjs对象,不是Date - Form.Item 嵌套 — 多个组件在同一个 Item 内用
getValueFromEvent处理
总结
Ant Design 5.x 的 token 主题系统、Form 的声明式校验、Table 的虚拟滚动等特性,使其成为中后台项目的不二之选。合理利用这些特性可以大幅提升开发效率和用户体验。
评论加载中...