返回

让你的表单更强大!Antd Form.List 玩转嵌套多级动态增减表单和校验

前端

Ant Design Form.List:动态增减表单的利器

什么是 Ant Design Form.List?

在现代 Web 开发中,动态增减表单的需求比比皆是。例如,当用户需要添加多个地址或填写多组商品信息时。传统的表单结构难以满足此类需求,而 Ant Design 的 Form.List 应运而生。

Form.List 是一个强大的组件,可帮助您轻松实现动态增减表单的功能。它提供了一系列 API,可用于动态添加或删除表单项,以及对表单项进行校验。

安装和使用

在项目中使用 Form.List 之前,需要先安装 Ant Design 和 Form.List:

npm install antd
npm install @ant-design/form

安装完成后,即可在项目中使用 Form.List。

嵌套多级动态增减表单

Form.List 支持嵌套多级表单。例如,我们可以创建一个表单,其中包含多个地址信息,每个地址信息又包含街道、城市、省份和邮编四个字段。

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

const App = () => {
  const [addresses, setAddresses] = useState([]);

  const onFinish = (values) => {
    console.log('Received values of form: ', values);
  };

  const addAddress = () => {
    setAddresses([...addresses, {}]);
  };

  const removeAddress = (index) => {
    const newAddresses = [...addresses];
    newAddresses.splice(index, 1);
    setAddresses(newAddresses);
  };

  return (
    <Form onFinish={onFinish}>
      <List>
        {addresses.map((address, index) => (
          <List.Item key={index}>
            <Form.Item label="街道" name={['addresses', index, 'street']}>
              <Input />
            </Form.Item>
            <Form.Item label="城市" name={['addresses', index, 'city']}>
              <Input />
            </Form.Item>
            <Form.Item label="省份" name={['addresses', index, 'province']}>
              <Input />
            </Form.Item>
            <Form.Item label="邮编" name={['addresses', index, 'zipCode']}>
              <Input />
            </Form.Item>
            <Button type="primary" onClick={() => removeAddress(index)}>删除</Button>
          </List.Item>
        ))}
      </List>
      <Button type="primary" onClick={addAddress}>添加地址</Button>
      <Button type="primary" htmlType="submit">提交</Button>
    </Form>
  );
};

export default App;

动态校验

Form.List 还支持动态校验。我们可以通过 validateFields 方法对表单项进行校验。如果校验通过,则返回 true;否则,返回一个包含错误信息的数组。

例如,我们可以对上面的表单进行校验,确保每个地址信息都填写完整。

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

const App = () => {
  const [addresses, setAddresses] = useState([]);

  const onFinish = (values) => {
    console.log('Received values of form: ', values);
  };

  const addAddress = () => {
    setAddresses([...addresses, {}]);
  };

  const removeAddress = (index) => {
    const newAddresses = [...addresses];
    newAddresses.splice(index, 1);
    setAddresses(newAddresses);
  };

  const validateAddress = (address) => {
    if (!address.street) {
      return '请填写街道';
    }
    if (!address.city) {
      return '请填写城市';
    }
    if (!address.province) {
      return '请填写省份';
    }
    if (!address.zipCode) {
      return '请填写邮编';
    }
    return true;
  };

  const validateAddresses = () => {
    const errors = [];
    addresses.forEach((address, index) => {
      const error = validateAddress(address);
      if (error) {
        errors.push({ name: ['addresses', index], errors: [error] });
      }
    });
    return errors;
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    const errors = validateAddresses();
    if (errors.length > 0) {
      Form.List.validateFieldsAndScroll(errors).catch((errorInfo) => {
        console.error('Error: ', errorInfo);
      });
      return;
    }

    onFinish(e);
  };

  return (
    <Form onSubmit={handleSubmit}>
      <List>
        {addresses.map((address, index) => (
          <List.Item key={index}>
            <Form.Item label="街道" name={['addresses', index, 'street']}>
              <Input />
            </Form.Item>
            <Form.Item label="城市" name={['addresses', index, 'city']}>
              <Input />
            </Form.Item>
            <Form.Item label="省份" name={['addresses', index, 'province']}>
              <Input />
            </Form.Item>
            <Form.Item label="邮编" name={['addresses', index, 'zipCode']}>
              <Input />
            </Form.Item>
            <Button type="primary" onClick={() => removeAddress(index)}>删除</Button>
          </List.Item>
        ))}
      </List>
      <Button type="primary" onClick={addAddress}>添加地址</Button>
      <Button type="primary" htmlType="submit">提交</Button>
    </Form>
  );
};

export default App;

结语

Ant Design Form.List 是构建动态增减表单和实现动态校验的利器。它可以帮助我们创建更加灵活、更加强大的表单,满足复杂多变的业务需求。

常见问题解答

  1. 如何使用 Form.List 嵌套多级表单?

    通过 children 属性可以嵌套多级表单。

  2. 如何实现动态校验?

    可以使用 validateFields 方法对表单项进行校验。

  3. 如何添加和删除表单项?

    可以通过 addAddressremoveAddress 方法动态添加和删除表单项。

  4. 如何使用 Form.List 处理嵌套数据?

    使用嵌套对象结构,例如 ['addresses', index, 'street'] 来处理嵌套数据。

  5. 如何解决 Form.List 的常见问题?

    检查控制台中的错误消息,并确保正确使用 API。