• 作者:老汪软件技巧
  • 发表时间:2024-09-02 00:04
  • 浏览量:

Ant Design 目前被广泛应用于企业级后台项目,甚至会被作为对外站点的 UI 库选择,构建 C 端业务。

目前我所在的公司就是使用 Ant Design 来构建网页。开发过程中比较常用的一些组件和它的使用方式,我也写了几篇文章,有兴趣的读者可以阅读:

如何基于 Ant Design 创建动态表单?关于 Ant Design 上传组件 的入门教程关于 Ant Design 选择组件 的入门教程

本期我们将继续这个系列,讨论的对象是关于如何实现单行多列表单布局。如果你经常跟表单页面打交道,那么对这个布局方式应该并不陌生。

老规矩,我们先从创建项目开始。

创建项目

使用 Vite 的 React 模板。

npm create vite@latest my-react-app -- --template react
Scaffolding project in /Users/xt02121/pg/my-react-app...
Done. Now run:
  cd my-react-app
  npm install
  npm run dev

进入项目,安装依赖:

cd my-react-app
npm install
npm run dev

使用 VS Code 打开项目:

code .

安装 @vitejs/plugin-react-swc 依赖,加快项目编译(可选):

npm i -D @vitejs/plugin-react-swc

// vite.config.js
import { defineConfig } from 'vite'
+ import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()]
})

安装 Ant Design 依赖:

npm install antd

删除 src/index.css 中的内容,src/App.jsx 改成下面这样:

import { FormDemo } from './FormDemo'
function App() {
  return (
    <FormDemo />
  )
}
export default App

创建 FormDemo.jsx:

import { Form, Input, Button } from 'antd'
export function FormDemo() {
  return <Form style={{ width: 600 }}>
    <Form.Item label="用户名">
      <Input placeholder="请输入用户名" />
    Form.Item>
    <Form.Item label="密码">
      <Input.Password placeholder="请输入密码" />
    Form.Item>
    <Form.Item>
      <Button htmlType="submit">登录Button>
    Form.Item>
  Form>
}

查看效果:

接下来进入正文,来看看 Ant Design 中如何实现单行多列的表单布局。

layout="inline"

提供了一个 layout prop,可以帮助我们最快实现行内多列布局。

- 
+

效果如下:

你会发现,设置成行业布局以后,每一个 .ant-form-item 会设置 margin-inline-end: 16px; 外边距,在默认文档流下,就是右外边距。

当然,在不设置 layout prop 情况下,我们还可以通过 控制表单项在一行展示。

- import { Form, Input, Button } from 'antd'
+ import { Form, Input, Button, Space } from 'antd'

+ 
  {/* ... */}
+ 

移除 layout prop,同时将 们包裹在 之中(size 指定项目间的间隔,这里设置成 16px)。

查看效果:

发现与上面一样。可以看到, 其实就是一个 Flex 容器,其中的元素默认就是横向排列的,设置的 size 其实就是在指定 gap 属性,约定项目间的间隔。

表单布局的优缺点_表单布局设计_

当然,有时还会遇到一个表单字段是由多个输入框构成的情况。

这个时候,就要搭配 + 一起使用了。

<Form.Item label="BirthDate" style={{ marginBottom: 0 }}>
  <Space size={16}>
    <Form.Item name="year" noStyle rules={[{ required: true }]}>
      <Input placeholder="Input birth year" />
    Form.Item>
    <Form.Item name="month" noStyle rules={[{ required: true }]}>
      <Input placeholder="Input birth month" />
    Form.Item>
  Space>
Form.Item>

没有 name 和 rules 的 就只是单纯用来展示 Label 标签的;而设置了 noStyle 的 不会实际渲染 HTML 结构,但依然会保留表单字段收集和校验的能力。

而 、 之间的 则是用来保证两个输入字段可以一行排列。

除了 ,还有 帮助我们实现更加紧凑的表单布局。

<Space.Compact>
  <Form.Item>
    <Input placeholder="请输入用户名" />
  Form.Item>
  <Form.Item>
    <Input.Password placeholder="请输入密码" />
  Form.Item>
  <Form.Item>
    <Button htmlType="submit">登录Button>
  Form.Item>
Space.Compact>

查看效果:

发现表单是一行排列了,但表单之间的分割线会有点粗。这是因为 中的元素默认是有边框样式的,那么拼在一起自然会多出 1 像素的粗度。

这个问题可以通过给 设置 noStyle prop 搞定:

<Space.Compact>
  <Form.Item noStyle>
    <Input placeholder="请输入用户名" />
  Form.Item>
  <Form.Item noStyle>
    <Input.Password placeholder="请输入密码" />
  Form.Item>
  <Form.Item noStyle>
    <Button htmlType="submit">登录Button>
  Form.Item>
Space.Compact>

给 设置 noStyle 后,最终渲染出来的 HTML 中不包含 的结构(不过 的校验逻辑还会保留),相当于把内部元素的结构暴露出来了。

效果如下:

发现元素之间的边线变成 1 恢复正常了。

这是因为除第一个和最后一个的元素的边框都设置成 0 了。

、 vs

不过使用 实现多表单一行布局会有个限制,就是即便表单容器很宽,但内部输入框的宽度也不会自动扩展到容器的边界。

以以下代码为例:

<Form>
  <Form.Item label="地址">
    <Space size={16}>
      <Form.Item
        name={["address", "province"]}
        noStyle
        rules={[{ required: true, message: "Province is required" }]}
      >
        <Select placeholder="Select province">
          <Select.Option value="Zhejiang">ZhejiangSelect.Option>
          <Select.Option value="Jiangsu">JiangsuSelect.Option>
        Select>
      Form.Item>
      <Form.Item
        name={["address", "street"]}
        noStyle
        rules={[{ required: true, message: "Street is required" }]}
      >
        <Input placeholder="Input street" />
      Form.Item>
    Space>
  Form.Item>
Form>

渲染效果如下:

但实际内容区宽度占据了整个剩余的宽度的:

这个就可以考虑使用 、 了。

<Form.Item label="地址">
  <Row gutter={16}>
    <Col span={12}>
      <Form.Item
        name={["address", "province"]}
        noStyle
        rules={[{ required: true, message: "Province is required" }]}
      >
        <Select placeholder="Select province">
          <Select.Option value="Zhejiang">ZhejiangSelect.Option>
          <Select.Option value="Jiangsu">JiangsuSelect.Option>
        Select>
      Form.Item>
    Col>
    <Col span={12}>
      <Form.Item
        name={["address", "street"]}
        noStyle
        rules={[{ required: true, message: "Street is required" }]}
      >
        <Input placeholder="Input street" />
      Form.Item>
    Col>
  Row>
Form.Item>

将 替换为 ,同时使用 包裹每一个 ,同时指定 span prop。Ant Design 设计系统将每一行 分成 24 等份, 就表示当前的 占据 1/2 行宽。

效果如下:

至此,我们就实现了能够填充预留宽度的多列布局方式。

总结

本文我讲解了如何在 Ant Design 中实现单行多列表单的布局方式。包括: layout="inline"、、 以及 和。

layout="inline" 是最简单的实现方式、 则是用来实现局部字段一行布局当你期望表单能够自动扩展占据剩余宽度的效果时,可以考虑 和 的组织方式

从 1 到 3,组织方式是一点点复杂的,而灵活度是慢慢增加的,你可以根据实际场景需要选择合适的方法。

好了,希望本文的介绍对你的工作能有所帮助。感谢你的阅读,再见。