Bạn đã từng trải qua qua khoảnh khắc ngồi trước màn hình, đối diện với vô vàn quyết định về giao diện: button nên để màu gì? Layout thế nào để nhìn gọn gàng nhưng vẫn đẹp mắt? Menu đặt ở bên trái hay bên phải? Làm sao để xây dựng admin dashboard vừa trực quan, vừa gọn, lại chuyên nghiệp, để khách hàng của bạn vừa nhìn vào là hiểu?
Mình tình cờ biết đến Ant Design (AntD). Ban đầu, cái tên nghe khá lạ, mình nghĩ "Ant" (kiến) thì có gì đặc biệt? Nhưng sau khi dạo một vòng, đọc tài liệu, xem demo trên trang chủ chính thức, mình nhận ra: Đây chính là một design system hoàn thiện chứ không đơn thuần là cung cấp các base components.
Trong bài viết này, cùng mình đi hết hành trình để hiểu được tại sao Ant Design lại đặc biệt. Bên cạnh đó, mình cũng sẽ hướng dẫn bạn làm thế nào để cài đặt và sử dụng nó trong dự án React, tùy chỉnh theme. Đồng thời, mình cũng chia sẻ những trải nghiệm cá nhân mình khi sử dụng AntD.
1. Ant Design là gì?
Ant Design (AntD) là một hệ thống thiết kế UI dành cho web, đặc biệt mạnh mẽ trong hệ sinh thái React. Nó không đơn thuần là một bộ thư viện component, mà là một design system hoàn chỉnh, được phát triển bởi Ant Financial (thuộc Alibaba Group).
Vậy tại sao AntD lại ra đời? - Ban đầu, AntD được Ant Financial phát triển để phục vụ nội bộ, giải quyết nhu cầu xây dựng các ứng dụng phức tạp, nhiều form, nhiều bảng dữ liệu, nhiều tương tác. Sau này, họ quyết định open-source, chia sẻ sản phẩm này với cộng đồng. AntD nhanh chóng được ưa chuộng, đặc biệt với các React developer.
Những tính năng chính của AntD:
- Hơn 50+ từ base component (Button, Input,...) đến những components phức tạp (DatePicker, TreeSelect, Table, Form,...)
- Bạn có thể tuỳ chỉnh theme, màu sắc, kiểu chữ, kích thước.
- AntD có tài liệu chi tiết, ví dụ thực tế, cộng đồng sử dụng rộng rãi trên GitHub, StackOverflow.
- AntD kết hợp tốt với React Hook, Redux, Next.js,…
2. Tại sao nên sử dụng Ant Design?
Không phải ngẫu nhiên AntD được nhiều developer chọn lựa. Mình đã dùng qua nhiều thư viện UI, Material UI, Bootstrap, TailwindCSS. Mỗi cái đều có ưu điểm và hạn chế riêng. Nhưng với AntD, mình cảm thấy:
- Thiết kế của AntD rất phù hợp cho các ứng dụng quản trị, dashboard, hệ thống nội bộ. Nếu bạn cần giao diện cho phần mềm quản lý bán hàng, phân tích dữ liệu nội bộ, hay CRM, AntD là một lựa chọn hoàn hảo.
- Table với sorting, filtering, pagination; Form với validation; Modal, Drawer, Notification… Gần như mọi thành phần UI cần thiết đều đã có sẵn. Điều này giúp bạn tiết kiệm nhiều thời gian, không phải code lại từng dòng CSS từ đầu
- Trang chủ AntD có tài liệu rõ ràng, kèm vô số ví dụ code. Bạn gặp vấn đề? Chỉ cần tìm kiếm, rất có thể cộng đồng đã có người từng mắc lỗi giống bạn và được giải đáp từ trước.
- Bạn có thể custom lại màu sắc, font chữ, kích thước component. Từ đó, bạn vừa tận dụng được khung sườn AntD, vừa tạo dấu ấn riêng cho thương hiệu hoặc sản phẩm.
Bên cạnh đó, mình cũng thấy một vài nhược điểm nhỏ:
- Kích thước bundle sẽ nặng nếu bạn import toàn bộ. Tuy nhiên, bạn có thể áp dụng tree-shaking để tối ưu.
- Phong cách mặc định có thể hơi cứng. Nếu bạn cần giao diện "phá cách" hoặc sặc sỡ, bạn sẽ phải tùy chỉnh rất nhiều.
3. Tìm hiểu về các components thường được sử dụng trong dự án
AntD có rất nhiều component. Mình sẽ giới thiệu vài component mình thường xuyên sử dụng trong nhiều dự án nhất, kèm theo ví dụ code để các bạn dễ hiểu nha.
3.1 Button
Button là một base component. AntD có nhiều type button: primary, default, dashed, text, link.
import { Button } from 'antd';
// ------------------------------------------
function ExampleButtons() {
return (
<div>
<Button type="primary">Primary</Button>
<Button>Default</Button>
<Button type="dashed">Dashed</Button>
<Button type="text">Text</Button>
<Button type="link">Link</Button>
</div>
);
}
Bạn có thêm icon, trạng thái loading
import { Button } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
// ------------------------------------------------
function ExampleIconButton() {
return (
<Button type="primary" icon={<SearchOutlined />} loading>
Tìm kiếm
</Button>
);
}
3.2 Input
Input cho phép bạn nhập dữ liệu. Có nhiều biến thể: Input thường, Input Password, Input với addon.
import { Input } from 'antd';
// -------------------------------------------------------
function ExampleInputs() {
return (
<div>
<Input placeholder="Nhập nội dung..." style={{ width: 200 }} />
<Input addonBefore="http://" addonAfter=".com" defaultValue="mysite" style={{ width: 300 }} />
<Input.Password placeholder="Nhập mật khẩu" style={{ width: 200 }} />
</div>
);
}
3.3 Form và Form.Item
import { Form, Input, Button } from 'antd';
// ------------------------------------------------
function ExampleForm() {
const [form] = Form.useForm();
const onFinish = (values) => {
console.log('Form data:', values);
};
return (
<Form form={form} onFinish={onFinish} layout="vertical" style={{ width: 300 }}>
<Form.Item name="username" label="Tên đăng nhập"
rules={[{ required: true, message: 'Vui lòng nhập tên đăng nhập!' }]}>
<Input />
</Form.Item>
<Form.Item name="password" label="Mật khẩu"
rules={[{ required: true, message: 'Vui lòng nhập mật khẩu!' }]}>
<Input.Password />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">Đăng nhập</Button>
</Form.Item>
</Form>
);
}
Việc validation form trở nên đơn giản và rõ ràng, giúp bạn ít phải code lại các logic kiểm tra dữ liệu.
3.4 Layout, Menu, Breadcrumb
Dùng Layout (với Header, Sider, Content, Footer) để tổ chức bố cục trang, kết hợp Menu tạo sidebar hoặc header navigation, Breadcrumb để hiển thị đường dẫn.
import { Layout, Menu } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
// -------------------------------------------------
function ExampleLayout() {
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider>
<div style={{ color: '#fff', textAlign: 'center', padding: '20px 0' }}>Logo</div>
<Menu theme="dark" mode="inline"
items={[
{ key: '1', label: 'Trang chủ' },
{ key: '2', label: 'Người dùng' },
{ key: '3', label: 'Cài đặt' },
]}
/>
</Sider>
<Layout>
<Header style={{ background: '#fff', paddingLeft: 20 }}>Header</Header>
<Content style={{ margin: 20, background: '#fff', padding: 20 }}>
Nội dung chính
</Content>
<Footer style={{ textAlign: 'center' }}>Ant Design ©2023 Created by Ant UED</Footer>
</Layout>
</Layout>
);
}
Với Breadcrumb:
import { Breadcrumb } from 'antd';
// ---------------------------------------------
function ExampleBreadcrumb() {
return (
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item>Trang chủ</Breadcrumb.Item>
<Breadcrumb.Item>Danh sách</Breadcrumb.Item>
<Breadcrumb.Item>Chi tiết</Breadcrumb.Item>
</Breadcrumb>
);
}
3.5 Modal
Modal để hiển thị hộp thoại pop-up
import { useState } from 'react';
import { Modal, Button } from 'antd';
// ----------------------------------------------
function ExampleModal() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>Mở Modal</Button>
<Modal title="Thông báo" open={open} onOk={() => setOpen(false)} onCancel={() => setOpen(false)}>
<p>Nội dung trong Modal</p>
</Modal>
</>
);
}
3.6 Table
Table là một thành phần mạnh mẽ, hỗ trợ sorting, filtering, pagination, và thậm chí editable cell.
import { Table } from 'antd';
// --------------------------------------------------------
const columns = [
{ title: 'Tên', dataIndex: 'name', key: 'name', sorter: (a,b) => a.name.localeCompare(b.name) },
{ title: 'Tuổi', dataIndex: 'age', key: 'age' },
{ title: 'Địa chỉ', dataIndex: 'address', key: 'address' },
];
const data = [
{ key:1, name:'Vy', age:23, address:'VietNam' },
{ key:2, name:'200Lab', age:100, address:'70 Huỳnh Văn Bánh, Phú Nhuận' },
{ key:3, name:'Thanh', age:22, address:'HCM' },
];
function ExampleTable() {
return <Table columns={columns} dataSource={data} />;
}
4. Custom Theme
Bạn có thể dùng ConfigProvider bọc App để custom lại theme
import { ConfigProvider } from 'antd';
// ------------------------------------
function ThemedApp() {
return (
<ConfigProvider
theme={{
token: {
colorPrimary: '#1DA57A',
borderRadius: 4,
},
}}
>
<App />
</ConfigProvider>
);
}
Mọi button, input, form,… sẽ sử dụng màu primary là #1DA57A
. Bạn có thể đổi font, cỡ chữ,...
Nếu bạn chỉ cần custom lại ít, bạn có thể dùng CSS module hoặc styled-components. Tuy nhiên, đừng lạm dụng việc override, hãy tận dụng theme để giữ tính nhất quán.
5. Những lưu ý khi sử dụng Ant Design
5.1 Giảm kích thước bundle
Sử dụng babel-plugin-import để chỉ import component cần thiết
// .babelrc
{
"plugins": [
["import", { "libraryName": "antd", "style": true }]
]
}
Giờ bạn có thể import import { Button } from 'antd';
mà không sợ bundle phình to quá.
5.2 Kết hợp với React Hook Form
Dù AntD Form rất mạnh, đôi lúc bạn vẫn muốn sử dụng React Hook Form. Không vấn đề, các Input, Select của AntD vẫn hoạt động tốt trong các "controller" form này. Bạn chỉ cần truyền prop onChange và value thích hợp.
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import { Input, Button, Form } from 'antd';
// -----------------------------------------------------
function ExampleHookForm() {
const { handleSubmit, control } = useForm({
defaultValues: {
username: '',
password: ''
}
});
const onSubmit = (data) => {
console.log('Dữ liệu từ form:', data);
};
return (
<Form layout="vertical" style={{ width: 300 }} onFinish={handleSubmit(onSubmit)}>
<Form.Item label="Tên đăng nhập" required>
<Controller
name="username"
control={control}
rules={{ required: 'Vui lòng nhập tên đăng nhập!' }}
render={({ field, fieldState }) => (
<>
<Input {...field} placeholder="Nhập tên đăng nhập" />
{fieldState.error && (
<div style={{ color: 'red' }}>{fieldState.error.message}</div>
)}
</>
)}
/>
</Form.Item>
<Form.Item label="Mật khẩu" required>
<Controller
name="password"
control={control}
rules={{ required: 'Vui lòng nhập mật khẩu!' }}
render={({ field, fieldState }) => (
<>
<Input.Password {...field} placeholder="Nhập mật khẩu" />
{fieldState.error && (
<div style={{ color: 'red' }}>{fieldState.error.message}</div>
)}
</>
)}
/>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">Đăng nhập</Button>
</Form.Item>
</Form>
);
}
export default ExampleHookForm;
ví dụ trên bạn có thể thấy cách kết hợp linh hoạt giữa UI component (AntD) và quản lý state, validation (React Hook Form). Bạn có thể dễ dàng mở rộng form, thêm các Input khác, thêm rules phức tạp hơn.
5.3 Layout Responsive
Dùng Row và Col để tạo layout responsive
import { Row, Col } from 'antd';
// -------------------------------------------------
function ResponsiveExample() {
return (
<Row gutter={[16,16]}>
<Col xs={24} sm={12} md={8} lg={6}>Cột 1</Col>
<Col xs={24} sm={12} md={8} lg={6}>Cột 2</Col>
<Col xs={24} sm={12} md={8} lg={6}>Cột 3</Col>
<Col xs={24} sm={12} md={8} lg={6}>Cột 4</Col>
</Row>
);
}
5.4 Icons
AntD icons (@ant-design/icons)
rất phong phú, đa dạng
import { SmileOutlined } from '@ant-design/icons';
// ------------------------------------------------
function IconExample() {
return <SmileOutlined style={{ fontSize: '24px', color: '#08c' }} />;
}
Trên hết thì đây là một vài lời khuyên của mình dành cho các bạn:
- Đọc tài liệu kỹ tại trang chính chủ:
https://ant.design/components/overview/
có rất nhiều ví dụ. Nên xem qua trước khi code, để chọn đúng component. - Xác định trước layout bạn cần các component nào, ví dụ như: sidebar, header, footer, breadcrumb,…. Từ đó đưa ra lựa chọn hợp lý.
- Điều chỉnh theme để khớp với thương hiệu, tránh override CSS quá nhiều.
- Tối ưu build, sử dụng babel-plugin-import hoặc tương tự, để code gọn và bundle nhỏ.
6. Kết luận
Ant Design mang đến cho bạn một system design hoàn chỉnh, giúp bạn xây dựng giao diện web chuyên nghiệp, thống nhất, và dồi dào tính năng. Nó đặc biệt hữu ích trong các ứng dụng doanh nghiệp, dashboard, hệ thống quản trị nội bộ, nơi bạn cần nhiều form, nhiều bảng, nhiều sự tương tác phức tạp.
Mình hy vọng bài viết này không chỉ giúp bạn hiểu sâu về AntD, mà còn truyền cảm hứng để bạn áp dụng nó vào dự án của riêng bạn, biến những ý tưởng thiết kế thành giao diện chuyên nghiệp một cách nhanh chóng.
Các bài viết liên quan:
Bài viết liên quan
Hướng dẫn tích hợp Sentry vào ứng dụng React
Dec 18, 2024 • 7 min read
MUI (Material UI): Công cụ rút ngắn thời gian xây dựng Giao diện
Dec 18, 2024 • 11 min read
Tìm hiểu Sentry: Công cụ Theo dõi Lỗi và Hiệu suất tự động
Dec 16, 2024 • 7 min read
Server-Side Rendering: Giải thích cơ chế hoạt động của SSR
Dec 11, 2024 • 15 min read
Client-Side Rendering: Giải thích cơ chế hoạt động của CSR
Dec 09, 2024 • 8 min read
Vercel là gì? Hướng dẫn deploy dự án Next.js bằng Vercel
Dec 07, 2024 • 14 min read