Ant Design 教程

项目概述

Ant Design 是一套企业级 UI 设计语言和 React 组件库,由阿里巴巴集团开发并维护。它提供了丰富的组件和设计资源,帮助开发者快速构建美观、一致的企业级应用。Ant Design 具有国际化支持、主题定制、响应式设计等特点,是国内最流行的 React UI 组件库之一。

主要特点

  • 丰富的组件库:提供了大量常用的 UI 组件
  • 国际化支持:内置多语言支持,方便构建全球化应用
  • 主题定制:支持自定义主题,满足不同品牌需求
  • 响应式设计:适配各种屏幕尺寸
  • TypeScript 支持:完整的类型定义
  • 设计规范统一:遵循 Ant Design 设计系统
  • 文档完善:详细的使用文档和示例
  • 社区活跃:拥有庞大的开发者社区

适用场景

  • 企业级应用
  • 管理后台
  • 数据密集型应用
  • 大型 Web 应用
  • 需要国际化支持的应用

安装与设置

方法一:使用 npm 或 yarn 安装

# 使用 npm
npm install antd

# 使用 yarn
yarn add antd

方法二:使用 CDN 引入

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Ant Design 示例</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/antd@5.12.8/dist/reset.css">
  <script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/antd@5.12.8/dist/antd.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script>
    const { Button } = antd;
    
    ReactDOM.render(
      <Button type="primary">Hello Ant Design</Button>,
      document.getElementById('root')
    );
  </script>
</body>
</html>

方法三:使用 Create React App

# 创建项目
npx create-react-app my-app
cd my-app

# 安装 antd
npm install antd

方法四:使用 Vite

# 创建项目
npm create vite@latest my-app -- --template react
cd my-app

# 安装 antd
npm install antd

核心概念

1. 组件使用

Ant Design 提供了丰富的组件,使用方式非常简单:

import React from 'react';
import { Button, Input, DatePicker } from 'antd';

function App() {
  return (
    <div>
      <Button type="primary">Primary Button</Button>
      <Input placeholder="Basic input" />
      <DatePicker />
    </div>
  );
}

export default App;

2. 布局系统

Ant Design 提供了灵活的布局系统,包括 Grid、Layout 等组件:

import React from 'react';
import { Layout, Grid } from 'antd';

const { Header, Sider, Content, Footer } = Layout;
const { Row, Col } = Grid;

function App() {
  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Header>Header</Header>
      <Layout>
        <Sider>Sider</Sider>
        <Content>
          <Row gutter={[16, 16]}>
            <Col span={8}>Column 1</Col>
            <Col span={8}>Column 2</Col>
            <Col span={8}>Column 3</Col>
          </Row>
        </Content>
      </Layout>
      <Footer>Footer</Footer>
    </Layout>
  );
}

export default App;

3. 主题定制

Ant Design 支持通过 ConfigProvider 或 less 变量定制主题:

使用 ConfigProvider

import React from 'react';
import { ConfigProvider, Button } from 'antd';

function App() {
  return (
    <ConfigProvider
      theme={{
        token: {
          colorPrimary: '#1890ff',
          borderRadius: 4,
        },
      }}
    >
      <Button type="primary">Primary Button</Button>
    </ConfigProvider>
  );
}

export default App;

使用 less 变量

src/vars.less 文件中定义变量:

// src/vars.less
@primary-color: #1890ff;
@border-radius-base: 4px;

然后在入口文件中引入:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './vars.less';
import './index.css';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

4. 国际化

Ant Design 内置了国际化支持,可以通过 ConfigProvider 设置语言:

import React from 'react';
import { ConfigProvider, Button, DatePicker } from 'antd';
import zhCN from 'antd/locale/zh_CN';

function App() {
  return (
    <ConfigProvider locale={zhCN}>
      <div>
        <Button type="primary">按钮</Button>
        <DatePicker />
      </div>
    </ConfigProvider>
  );
}

export default App;

5. 表单处理

Ant Design 提供了强大的表单组件,支持表单验证、联动等功能:

import React from 'react';
import { Form, Input, Button, Checkbox } from 'antd';

function App() {
  const onFinish = (values) => {
    console.log('Success:', values);
  };

  const onFinishFailed = (errorInfo) => {
    console.log('Failed:', errorInfo);
  };

  return (
    <Form
      name="basic"
      labelCol={{ span: 8 }}
      wrapperCol={{ span: 16 }}
      onFinish={onFinish}
      onFinishFailed={onFinishFailed}
      autoComplete="off"
    >
      <Form.Item
        label="Username"
        name="username"
        rules={[{ required: true, message: 'Please input your username!' }]}
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="Password"
        name="password"
        rules={[{ required: true, message: 'Please input your password!' }]}
      >
        <Input.Password />
      </Form.Item>

      <Form.Item name="remember" valuePropName="checked" wrapperCol={{ offset: 8, span: 16 }}>
        <Checkbox>Remember me</Checkbox>
      </Form.Item>

      <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
}

export default App;

6. 状态管理

Ant Design 组件通常通过 props 和 state 进行状态管理:

import React, { useState } from 'react';
import { Table, Button } from 'antd';

function App() {
  const [data, setData] = useState([
    { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
    { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
    { key: '3', name: 'Joe Black', age: 32, address: 'Sydney No. 1 Lake Park' },
  ]);

  const columns = [
    { title: 'Name', dataIndex: 'name', key: 'name' },
    { title: 'Age', dataIndex: 'age', key: 'age' },
    { title: 'Address', dataIndex: 'address', key: 'address' },
    { 
      title: 'Action', 
      key: 'action',
      render: () => <Button type="primary">Edit</Button>
    },
  ];

  return <Table columns={columns} dataSource={data} />;
}

export default App;

常用组件

1. Button

按钮组件用于触发操作:

import React from 'react';
import { Button } from 'antd';

function ButtonExample() {
  return (
    <div>
      <Button type="primary">Primary Button</Button>
      <Button>Default Button</Button>
      <Button type="dashed">Dashed Button</Button>
      <Button type="text">Text Button</Button>
      <Button type="link">Link Button</Button>
    </div>
  );
}

export default ButtonExample;

2. Form

表单组件用于收集用户输入:

import React from 'react';
import { Form, Input, Button, Select, DatePicker } from 'antd';

const { Option } = Select;

function FormExample() {
  const onFinish = (values) => {
    console.log('Success:', values);
  };

  return (
    <Form
      name="complex-form"
      labelCol={{ span: 8 }}
      wrapperCol={{ span: 16 }}
      onFinish={onFinish}
    >
      <Form.Item
        label="Name"
        name="name"
        rules={[{ required: true, message: 'Please input your name!' }]}
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="Gender"
        name="gender"
        rules={[{ required: true, message: 'Please select your gender!' }]}
      >
        <Select placeholder="Select a option">
          <Option value="male">Male</Option>
          <Option value="female">Female</Option>
        </Select>
      </Form.Item>

      <Form.Item
        label="Birth Date"
        name="birthDate"
        rules={[{ required: true, message: 'Please select your birth date!' }]}
      >
        <DatePicker style={{ width: '100%' }} />
      </Form.Item>

      <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
        <Button type="primary" htmlType="submit">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
}

export default FormExample;

3. Table

表格组件用于展示数据:

import React from 'react';
import { Table, Button } from 'antd';

function TableExample() {
  const columns = [
    { title: 'Name', dataIndex: 'name', key: 'name' },
    { title: 'Age', dataIndex: 'age', key: 'age' },
    { title: 'Address', dataIndex: 'address', key: 'address' },
    { 
      title: 'Action', 
      key: 'action',
      render: (_, record) => (
        <div>
          <Button type="primary" size="small" style={{ marginRight: 8 }}>
            Edit
          </Button>
          <Button danger size="small">
            Delete
          </Button>
        </div>
      ),
    },
  ];

  const data = [
    { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
    { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
    { key: '3', name: 'Joe Black', age: 32, address: 'Sydney No. 1 Lake Park' },
    { key: '4', name: 'Jim Red', age: 32, address: 'London No. 2 Lake Park' },
  ];

  return <Table columns={columns} dataSource={data} />;
}

export default TableExample;

4. Modal

对话框组件用于显示重要信息或请求用户确认:

import React, { useState } from 'react';
import { Button, Modal, Form, Input } from 'antd';

function ModalExample() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [form] = Form.useForm();

  const showModal = () => {
    setIsModalOpen(true);
  };

  const handleOk = () => {
    form.validateFields().then(values => {
      console.log('Success:', values);
      setIsModalOpen(false);
      form.resetFields();
    });
  };

  const handleCancel = () => {
    setIsModalOpen(false);
    form.resetFields();
  };

  return (
    <div>
      <Button type="primary" onClick={showModal}>
        Open Modal
      </Button>
      <Modal
        title="Basic Modal"
        open={isModalOpen}
        onOk={handleOk}
        onCancel={handleCancel}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="name"
            label="Name"
            rules={[{ required: true, message: 'Please input your name!' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="description"
            label="Description"
          >
            <Input.TextArea rows={4} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}

export default ModalExample;

5. Menu

菜单组件用于导航:

import React, { useState } from 'react';
import { Menu } from 'antd';

function MenuExample() {
  const [current, setCurrent] = useState('1');

  const items = [
    {
      key: '1',
      label: 'Navigation One',
    },
    {
      key: '2',
      label: 'Navigation Two',
      children: [
        { key: '2-1', label: 'Option 1' },
        { key: '2-2', label: 'Option 2' },
        { key: '2-3', label: 'Option 3' },
      ],
    },
    {
      key: '3',
      label: 'Navigation Three',
    },
  ];

  const onClick = (e) => {
    console.log('click ', e);
    setCurrent(e.key);
  };

  return <Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} />;
}

export default MenuExample;

6. Card

卡片组件用于展示相关信息的集合:

import React from 'react';
import { Card, Button } from 'antd';

function CardExample() {
  return (
    <div>
      <Card
        title="Card Title"
        extra={<Button type="link">More</Button>}
        style={{ width: 300 }}
      >
        <p>Card content</p>
        <p>Card content</p>
        <p>Card content</p>
      </Card>
    </div>
  );
}

export default CardExample;

7. Tabs

标签页组件用于在同一页面中切换不同的内容:

import React from 'react';
import { Tabs } from 'antd';

function TabsExample() {
  const items = [
    {
      key: '1',
      label: 'Tab 1',
      children: 'Content of Tab Pane 1',
    },
    {
      key: '2',
      label: 'Tab 2',
      children: 'Content of Tab Pane 2',
    },
    {
      key: '3',
      label: 'Tab 3',
      children: 'Content of Tab Pane 3',
    },
  ];

  return <Tabs items={items} />;
}

export default TabsExample;

8. Select

选择器组件用于从选项中选择值:

import React, { useState } from 'react';
import { Select } from 'antd';

const { Option } = Select;

function SelectExample() {
  const [value, setValue] = useState('');

  const handleChange = (newValue) => {
    setValue(newValue);
  };

  return (
    <Select
      style={{ width: 120 }}
      value={value}
      onChange={handleChange}
      placeholder="Select a person"
      options={[
        { value: 'jack', label: 'Jack' },
        { value: 'lucy', label: 'Lucy' },
        { value: 'Yiminghe', label: 'yiminghe' },
      ]}
    />
  );
}

export default SelectExample;

高级功能

1. 权限管理

Ant Design 可以与权限管理系统集成,根据用户权限显示或隐藏组件:

import React from 'react';
import { Button, Menu } from 'antd';

// 模拟权限检查函数
const hasPermission = (permission) => {
  // 实际应用中,这里应该从权限系统获取用户权限
  const userPermissions = ['read', 'write'];
  return userPermissions.includes(permission);
};

// 权限控制组件
const Authorized = ({ permission, children }) => {
  if (hasPermission(permission)) {
    return children;
  }
  return null;
};

function PermissionExample() {
  return (
    <div>
      <Button>Everyone can see</Button>
      <Authorized permission="write">
        <Button type="primary">Only writers can see</Button>
      </Authorized>
      <Menu>
        <Menu.Item key="1">Home</Menu.Item>
        <Authorized permission="admin">
          <Menu.Item key="2">Admin Panel</Menu.Item>
        </Authorized>
      </Menu>
    </div>
  );
}

export default PermissionExample;

2. 自定义组件

除了使用内置组件外,你还可以基于 Ant Design 构建自定义组件:

import React from 'react';
import { Input, Button, Tooltip } from 'antd';
import { SearchOutlined } from '@ant-design/icons';

function SearchBox({ placeholder, onSearch }) {
  const [value, setValue] = React.useState('');

  const handleSearch = () => {
    if (onSearch) {
      onSearch(value);
    }
  };

  const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      handleSearch();
    }
  };

  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <Input
        placeholder={placeholder || 'Search'}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        onKeyPress={handleKeyPress}
        prefix={<SearchOutlined />}
      />
      <Tooltip title="Search">
        <Button type="primary" onClick={handleSearch}>
          Search
        </Button>
      </Tooltip>
    </div>
  );
}

export default SearchBox;

3. 性能优化

对于大型应用,可以使用一些技巧来优化 Ant Design 组件的性能:

使用 React.memo

import React, { memo } from 'react';
import { Table } from 'antd';

const columns = [
  { title: 'Name', dataIndex: 'name' },
  { title: 'Age', dataIndex: 'age' },
  { title: 'Address', dataIndex: 'address' },
];

const DataTable = memo(({ data }) => {
  return <Table columns={columns} dataSource={data} />;
});

function App() {
  const [data, setData] = React.useState([
    { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
    { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
  ]);

  return (
    <div>
      <DataTable data={data} />
      <Button onClick={() => setData([...data, { key: '3', name: 'Joe Black', age: 32, address: 'Sydney No. 1 Lake Park' }])}>
        Add Data
      </Button>
    </div>
  );
}

export default App;

使用虚拟滚动

对于长列表,可以使用虚拟滚动来提高性能:

import React from 'react';
import { List, Avatar } from 'antd';
import { VirtualList } from 'antd/lib/list/VirtualList';

function VirtualListExample() {
  const data = [];
  for (let i = 0; i < 1000; i++) {
    data.push({
      id: i,
      name: `Item ${i}`,
      avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${i}`,
    });
  }

  const itemHeight = 47;
  const containerHeight = 400;

  return (
    <VirtualList
      data={data}
      height={containerHeight}
      itemHeight={itemHeight}
      itemKey="id"
    >
      {(item) => (
        <List.Item key={item.id}>
          <List.Item.Meta
            avatar={<Avatar src={item.avatar} />}
            title={<a href="#">{item.name}</a>}
            description="This is a description"
          />
        </List.Item>
      )}
    </VirtualList>
  );
}

export default VirtualListExample;

4. 主题切换

Ant Design 支持运行时主题切换:

import React, { useState } from 'react';
import { ConfigProvider, Button, Space } from 'antd';

function ThemeSwitcher() {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(theme === 'light' ? 'dark' : 'light');
  };

  return (
    <ConfigProvider
      theme={{
        algorithm: theme === 'light' ? undefined : ConfigProvider.theme.darkAlgorithm,
      }}
    >
      <div style={{ padding: 24, minHeight: 200, backgroundColor: theme === 'light' ? '#f0f2f5' : '#141414', color: theme === 'light' ? '#000' : '#fff' }}>
        <Space direction="vertical">
          <div>Current theme: {theme}</div>
          <Button type="primary">Primary Button</Button>
          <Button>Default Button</Button>
          <Button type="dashed">Dashed Button</Button>
          <Button onClick={toggleTheme}>Toggle Theme</Button>
        </Space>
      </div>
    </ConfigProvider>
  );
}

export default ThemeSwitcher;

最佳实践

1. 组件组织

  • 按功能模块组织组件
  • 使用文件夹结构管理相关组件
  • 为组件添加清晰的文档和注释

2. 样式管理

  • 使用 Ant Design 提供的样式变量
  • 避免直接覆盖组件样式
  • 对于自定义样式,使用 BEM 命名规范

3. 性能优化

  • 使用 React.memo 缓存组件
  • 对于长列表,使用虚拟滚动
  • 合理使用 useMemo 和 useCallback
  • 避免在 render 函数中创建不必要的对象

4. 可访问性

  • 确保所有组件都有适当的 ARIA 属性
  • 测试组件在屏幕阅读器中的表现
  • 确保键盘导航正常工作

5. 国际化

  • 使用 Ant Design 的国际化功能
  • 提取所有用户可见的文本到国际化文件
  • 考虑不同语言的文本长度差异

6. 测试

  • 为组件编写单元测试
  • 测试组件在不同主题下的表现
  • 测试组件的响应式行为
  • 测试表单验证逻辑

常见问题与解决方案

1. 样式冲突

问题:Ant Design 样式与项目其他样式冲突。

解决方案

  • 使用 CSS Modules 或 styled-components
  • 为 Ant Design 组件添加前缀
  • 使用 ConfigProvider 的 prefixCls 属性

2. 组件渲染性能问题

问题:大型表单或表格渲染缓慢。

解决方案

  • 使用虚拟滚动
  • 优化组件渲染,避免不必要的重新渲染
  • 使用 React.lazy 和 Suspense 懒加载组件

3. 国际化配置问题

问题:国际化配置不生效。

解决方案

  • 确保正确导入语言包
  • 检查 ConfigProvider 的配置
  • 验证组件是否支持国际化

4. 主题定制问题

问题:主题定制不生效。

解决方案

  • 确保正确配置主题变量
  • 检查样式加载顺序
  • 验证组件是否支持主题定制

5. 兼容性问题

问题:在某些浏览器中组件显示异常。

解决方案

  • 检查 Ant Design 的浏览器兼容性
  • 使用 Babel 和 Polyfill
  • 测试在目标浏览器中的表现

参考资源

总结

Ant Design 是一套功能强大、设计精美的企业级 UI 组件库,它提供了丰富的组件和设计资源,帮助开发者快速构建美观、一致的企业级应用。通过本教程的学习,你应该已经掌握了 Ant Design 的核心概念、使用方法和最佳实践。

Ant Design 的生态系统非常丰富,包括 Ant Design Pro(中后台解决方案)、Ant Design Mobile(移动端组件库)、Ant Design Charts(图表库)等。这些工具可以帮助你更高效地构建各种类型的应用。

作为国内最流行的 React UI 组件库之一,Ant Design 拥有庞大的开发者社区和完善的文档,这使得它成为构建企业级应用的理想选择。无论是管理后台、数据可视化还是业务系统,Ant Design 都能满足你的需求。

随着 Ant Design 的不断发展,它也在持续改进和更新,添加新的组件和功能,以适应现代 Web 开发的需求。建议你持续关注 Ant Design 的官方文档和社区动态,以便及时了解最新的功能和最佳实践。

« 上一篇 shadcn/ui 教程 - 可定制的 UI 组件库 下一篇 » Material-UI 教程 - 基于 Material Design 的 React 组件库