第一个 Ant Design 应用 #

创建项目 #

首先,创建一个新的 React 项目:

bash
npm create vite@latest my-first-antd -- --template react-ts

cd my-first-antd

npm install

npm install antd @ant-design/icons

项目结构 #

text
my-first-antd/
├── src/
│   ├── components/
│   │   └── UserForm.tsx
│   ├── App.tsx
│   ├── App.css
│   ├── main.tsx
│   └── index.css
├── package.json
└── vite.config.ts

入口文件配置 #

main.tsx #

tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/locale/zh_CN';
import App from './App';
import './index.css';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ConfigProvider
      locale={zhCN}
      theme={{
        token: {
          colorPrimary: '#1677ff',
          borderRadius: 6,
        },
      }}
    >
      <App />
    </ConfigProvider>
  </React.StrictMode>
);

创建用户表单组件 #

components/UserForm.tsx #

tsx
import { Form, Input, Button, Select, DatePicker, Radio, Space } from 'antd';
import { UserOutlined, MailOutlined, PhoneOutlined } from '@ant-design/icons';

const { Option } = Select;

interface UserFormValues {
  name: string;
  email: string;
  phone: string;
  gender: string;
  birthday: any;
  city: string;
}

const UserForm: React.FC = () => {
  const [form] = Form.useForm();

  const onFinish = (values: UserFormValues) => {
    console.log('表单数据:', values);
  };

  const onReset = () => {
    form.resetFields();
  };

  return (
    <Form
      form={form}
      layout="vertical"
      onFinish={onFinish}
      initialValues={{
        gender: 'male',
      }}
    >
      <Form.Item
        name="name"
        label="姓名"
        rules={[{ required: true, message: '请输入姓名' }]}
      >
        <Input prefix={<UserOutlined />} placeholder="请输入姓名" />
      </Form.Item>

      <Form.Item
        name="email"
        label="邮箱"
        rules={[
          { required: true, message: '请输入邮箱' },
          { type: 'email', message: '请输入有效的邮箱地址' },
        ]}
      >
        <Input prefix={<MailOutlined />} placeholder="请输入邮箱" />
      </Form.Item>

      <Form.Item
        name="phone"
        label="手机号"
        rules={[
          { required: true, message: '请输入手机号' },
          { pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号' },
        ]}
      >
        <Input prefix={<PhoneOutlined />} placeholder="请输入手机号" />
      </Form.Item>

      <Form.Item name="gender" label="性别">
        <Radio.Group>
          <Radio value="male">男</Radio>
          <Radio value="female">女</Radio>
        </Radio.Group>
      </Form.Item>

      <Form.Item name="birthday" label="出生日期">
        <DatePicker style={{ width: '100%' }} />
      </Form.Item>

      <Form.Item name="city" label="城市">
        <Select placeholder="请选择城市">
          <Option value="beijing">北京</Option>
          <Option value="shanghai">上海</Option>
          <Option value="guangzhou">广州</Option>
          <Option value="shenzhen">深圳</Option>
        </Select>
      </Form.Item>

      <Form.Item>
        <Space>
          <Button type="primary" htmlType="submit">
            提交
          </Button>
          <Button onClick={onReset}>重置</Button>
        </Space>
      </Form.Item>
    </Form>
  );
};

export default UserForm;

创建主应用 #

App.tsx #

tsx
import { useState } from 'react';
import {
  Layout,
  Menu,
  Card,
  Table,
  Button,
  Space,
  Tag,
  message,
  Modal,
} from 'antd';
import {
  UserOutlined,
  FormOutlined,
  TableOutlined,
  PlusOutlined,
} from '@ant-design/icons';
import UserForm from './components/UserForm';
import './App.css';

const { Header, Content, Sider } = Layout;

interface User {
  key: string;
  name: string;
  email: string;
  phone: string;
  status: string;
}

const App: React.FC = () => {
  const [currentMenu, setCurrentMenu] = useState('form');
  const [users, setUsers] = useState<User[]>([
    {
      key: '1',
      name: '张三',
      email: 'zhangsan@example.com',
      phone: '13800138000',
      status: 'active',
    },
    {
      key: '2',
      name: '李四',
      email: 'lisi@example.com',
      phone: '13900139000',
      status: 'inactive',
    },
  ]);
  const [modalVisible, setModalVisible] = useState(false);

  const columns = [
    {
      title: '姓名',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '邮箱',
      dataIndex: 'email',
      key: 'email',
    },
    {
      title: '手机号',
      dataIndex: 'phone',
      key: 'phone',
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      render: (status: string) => (
        <Tag color={status === 'active' ? 'green' : 'red'}>
          {status === 'active' ? '激活' : '未激活'}
        </Tag>
      ),
    },
    {
      title: '操作',
      key: 'action',
      render: (_: any, record: User) => (
        <Space>
          <Button type="link" size="small">
            编辑
          </Button>
          <Button type="link" size="small" danger>
            删除
          </Button>
        </Space>
      ),
    },
  ];

  const handleAddUser = () => {
    setModalVisible(true);
  };

  const handleMenuClick = (e: { key: string }) => {
    setCurrentMenu(e.key);
  };

  const showSuccess = () => {
    message.success('操作成功!');
  };

  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Sider width={200}>
        <div style={{ height: 32, margin: 16, background: '#fff' }} />
        <Menu
          mode="inline"
          defaultSelectedKeys={['form']}
          style={{ height: '100%', borderRight: 0 }}
          onClick={handleMenuClick}
          items={[
            {
              key: 'form',
              icon: <FormOutlined />,
              label: '表单示例',
            },
            {
              key: 'table',
              icon: <TableOutlined />,
              label: '表格示例',
            },
          ]}
        />
      </Sider>
      <Layout>
        <Header style={{ background: '#fff', padding: '0 24px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <h2 style={{ margin: 0 }}>Ant Design 示例应用</h2>
            <Button type="primary" icon={<PlusOutlined />} onClick={handleAddUser}>
              添加用户
            </Button>
          </div>
        </Header>
        <Content style={{ margin: 24 }}>
          {currentMenu === 'form' && (
            <Card title="用户信息表单">
              <UserForm />
            </Card>
          )}
          {currentMenu === 'table' && (
            <Card title="用户列表">
              <Table columns={columns} dataSource={users} />
            </Card>
          )}
        </Content>
      </Layout>
      <Modal
        title="添加用户"
        open={modalVisible}
        onCancel={() => setModalVisible(false)}
        footer={null}
      >
        <UserForm />
      </Modal>
    </Layout>
  );
};

export default App;

App.css #

css
.app {
  min-height: 100vh;
}

.logo {
  height: 32px;
  margin: 16px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 6px;
}

.site-layout-content {
  min-height: 280px;
  padding: 24px;
  background: #fff;
}

运行项目 #

bash
npm run dev

打开浏览器访问 http://localhost:5173,你将看到一个完整的管理后台界面。

代码解析 #

1. 布局组件 #

使用 Layout 组件创建页面结构:

tsx
<Layout>
  <Sider>侧边栏</Sider>
  <Layout>
    <Header>顶部导航</Header>
    <Content>内容区域</Content>
  </Layout>
</Layout>

2. 表单组件 #

使用 Form 组件创建表单:

tsx
<Form form={form} onFinish={onFinish}>
  <Form.Item name="name" label="姓名" rules={[{ required: true }]}>
    <Input />
  </Form.Item>
</Form>

3. 表格组件 #

使用 Table 组件展示数据:

tsx
<Table columns={columns} dataSource={data} />

4. 消息提示 #

使用 message 组件显示提示:

tsx
message.success('操作成功!');

功能演示 #

表单验证 #

表单支持多种验证规则:

tsx
<Form.Item
  name="email"
  rules={[
    { required: true, message: '请输入邮箱' },
    { type: 'email', message: '请输入有效的邮箱' },
  ]}
>
  <Input />
</Form.Item>

表格操作 #

表格支持自定义操作列:

tsx
{
  title: '操作',
  render: (_, record) => (
    <Space>
      <Button type="link">编辑</Button>
      <Button type="link" danger>删除</Button>
    </Space>
  ),
}

下一步 #

恭喜你完成了第一个 Ant Design 应用!接下来学习 设计价值观,深入理解 Ant Design 的设计理念。

最后更新:2026-03-28