Skip to content

React 组件设计全攻略:15+ 个核心 UI 组件设计模式与最佳实践

Published: at 12:00 AM

设计一个 Select 组件

<Select value="about" onChange={handleChange} placeholder="请选择">
  <Select.Option value="home">Home</Select.Option>
  <Select.Option value="about">About</Select.Option>
  <Select.Option value="blog">Blog</Select.Option>
</Select>

// 支持多选
<Select mode="multiple" value={['home', 'about']} onChange={handleChange}>
  <Select.Option value="home">Home</Select.Option>
  <Select.Option value="about">About</Select.Option>
  <Select.Option value="blog">Blog</Select.Option>
</Select>

设计要点:

设计一个 Icon 组件

<Icon type="right" />
<Icon type="loading" spin />
<Icon type="heart" style={{ color: 'red', fontSize: '20px' }} />

// 支持自定义图标
<Icon component={CustomSvg} />

设计要点:

设计一个 Layout 组件

<Layout>
  <Layout.Header>Header</Layout.Header>
  <Layout.Content>
    <Layout.Sider width={200}>Sider</Layout.Sider>
    <Layout.Content>Main Content</Layout.Content>
  </Layout.Content>
  <Layout.Footer>Footer</Layout.Footer>
</Layout>

// 响应式布局
<Layout responsive breakpoints={{ md: 768, lg: 1024 }}>
  <Layout.Sider
    collapsible
    collapsed={collapsed}
    onCollapse={setCollapsed}
  >
    Sidebar
  </Layout.Sider>
  <Layout.Content>Content</Layout.Content>
</Layout>

设计要点:

设计一个 Avatar 组件

<Avatar size="large" src="/user.jpg" />
<Avatar size={64} icon="user" />
<Avatar style={{ backgroundColor: '#87d068' }}>张</Avatar>

// 头像组
<Avatar.Group maxCount={3} size="large">
  <Avatar src="/user1.jpg" />
  <Avatar src="/user2.jpg" />
  <Avatar src="/user3.jpg" />
  <Avatar src="/user4.jpg" />
</Avatar.Group>

设计要点:

设计一个 Button 组件

<Button type="primary" size="large" onClick={handleClick}>
  Primary Button
</Button>

<Button type="default" loading={isLoading}>
  <Icon type="download" />
  Download
</Button>

<Button type="link" href="/about">
  Link Button
</Button>

// 按钮组
<Button.Group>
  <Button>Left</Button>
  <Button>Middle</Button>
  <Button>Right</Button>
</Button.Group>

设计要点:

设计一个 Input 组件

<Input
  placeholder="请输入用户名"
  value={username}
  onChange={(e) => setUsername(e.target.value)}
/>

<Input.Password
  placeholder="请输入密码"
  visibilityToggle
/>

<Input.Search
  placeholder="搜索"
  enterButton
  onSearch={handleSearch}
/>

<Input.TextArea
  rows={4}
  placeholder="请输入描述"
  maxLength={200}
  showCount
/>

设计要点:

设计一个 Modal 组件

<Modal
  title="确认删除"
  open={isModalOpen}
  onOk={handleOk}
  onCancel={handleCancel}
  okText="删除"
  cancelText="取消"
  okButtonProps={{ danger: true }}
>
  <p>确定要删除这个项目吗?此操作不可恢复。</p>
</Modal>;

// 函数式调用
Modal.confirm({
  title: "确认删除",
  content: "此操作不可恢复",
  onOk: () => handleDelete(),
});

设计要点:

设计一个 Table 组件

<Table
  dataSource={dataSource}
  columns={[
    {
      title: "姓名",
      dataIndex: "name",
      key: "name",
      sorter: true,
      render: (text, record) => <a>{text}</a>,
    },
    {
      title: "年龄",
      dataIndex: "age",
      key: "age",
      sorter: (a, b) => a.age - b.age,
    },
    {
      title: "操作",
      key: "action",
      render: (text, record) => (
        <Button type="link" onClick={() => handleEdit(record)}>
          编辑
        </Button>
      ),
    },
  ]}
  pagination={{
    current: currentPage,
    pageSize: 10,
    total: total,
    onChange: handlePageChange,
  }}
  rowSelection={{
    selectedRowKeys,
    onChange: setSelectedRowKeys,
  }}
/>

设计要点:

设计一个 Tabs 组件

<Tabs activeKey={activeKey} onChange={setActiveKey} type="card">
  <Tabs.TabPane tab="用户管理" key="users">
    <UserList />
  </Tabs.TabPane>
  <Tabs.TabPane tab="角色管理" key="roles">
    <RoleList />
  </Tabs.TabPane>
  <Tabs.TabPane
    tab={<span><Icon type="setting" />设置</span>}
    key="settings"
  >
    <Settings />
  </Tabs.TabPane>
</Tabs>

// 可编辑标签页
<Tabs
  type="editable-card"
  onEdit={(targetKey, action) => {
    if (action === 'add') {
      handleAddTab();
    } else {
      handleRemoveTab(targetKey);
    }
  }}
>
  {tabPanes}
</Tabs>

设计要点:

设计一个 Form 组件

<Form
  form={form}
  layout="vertical"
  onFinish={handleSubmit}
  initialValues={{ username: "", email: "" }}
>
  <Form.Item
    name="username"
    label="用户名"
    rules={[
      { required: true, message: "请输入用户名" },
      { min: 3, message: "用户名至少3个字符" },
    ]}
  >
    <Input placeholder="请输入用户名" />
  </Form.Item>

  <Form.Item
    name="email"
    label="邮箱"
    rules={[
      { required: true, message: "请输入邮箱" },
      { type: "email", message: "邮箱格式不正确" },
    ]}
  >
    <Input placeholder="请输入邮箱" />
  </Form.Item>

  <Form.Item>
    <Button type="primary" htmlType="submit">
      提交
    </Button>
  </Form.Item>
</Form>

设计要点:

设计一个 Card 组件

<Card
  title="卡片标题"
  extra={<Button type="link">更多</Button>}
  actions={[
    <Icon type="setting" />,
    <Icon type="edit" />,
    <Icon type="ellipsis" />
  ]}
>
  <p>卡片内容</p>
</Card>

<Card
  hoverable
  cover={<img src="/image.jpg" alt="cover" />}
  style={{ width: 300 }}
>
  <Card.Meta
    avatar={<Avatar src="/avatar.jpg" />}
    title="标题"
    description="描述信息"
  />
</Card>

设计要点:

设计一个 DatePicker 组件

<DatePicker
  placeholder="选择日期"
  onChange={handleDateChange}
  format="YYYY-MM-DD"
/>

<DatePicker.RangePicker
  placeholder={['开始日期', '结束日期']}
  onChange={handleRangeChange}
/>

<DatePicker
  showTime
  placeholder="选择日期时间"
  format="YYYY-MM-DD HH:mm:ss"
/>

设计要点:

设计一个 Upload 组件

<Upload
  action="/api/upload"
  listType="text"
  multiple
  onChange={handleUploadChange}
  beforeUpload={beforeUpload}
>
  <Button icon={<Icon type="upload" />}>上传文件</Button>
</Upload>

<Upload
  action="/api/upload"
  listType="picture-card"
  fileList={fileList}
  onPreview={handlePreview}
  onChange={handleChange}
>
  <div>
    <Icon type="plus" />
    <div style={{ marginTop: 8 }}>上传</div>
  </div>
</Upload>

// 拖拽上传
<Upload.Dragger
  action="/api/upload"
  multiple
  onChange={handleChange}
>
  <p><Icon type="inbox" style={{ fontSize: 48 }} /></p>
  <p>点击或拖拽文件到此区域上传</p>
</Upload.Dragger>

设计要点:

设计一个 Tooltip 组件

<Tooltip title="这是一个提示信息">
  <Button>悬浮显示提示</Button>
</Tooltip>

<Tooltip
  title="自定义内容"
  placement="topLeft"
  trigger="click"
  overlayStyle={{ maxWidth: 300 }}
>
  <span>点击显示提示</span>
</Tooltip>

设计要点:

设计一个 Loading 组件

<Loading spinning={isLoading}>
  <div>加载中的内容</div>
</Loading>

<Loading
  spinning={isLoading}
  tip="数据加载中..."
  size="large"
>
  <Table dataSource={data} columns={columns} />
</Loading>

// 独立的加载指示器
<Loading indicator={<Icon type="loading" spin />} />

设计要点:

设计一个 Pagination 组件

<Pagination
  current={currentPage}
  total={500}
  pageSize={20}
  onChange={handlePageChange}
  showSizeChanger
  showQuickJumper
  showTotal={(total, range) =>
    `第 ${range[0]}-${range[1]} 条/共 ${total} 条`
  }
/>

<Pagination
  simple
  current={currentPage}
  total={100}
  onChange={handlePageChange}
/>

设计要点: