返回

Antd4 Form实战开发(下):精益求精

前端

前言

大家有没有体会过,虽然Antd4的官方文档相对来说已经是足够清晰了,但是实际操作起来,总是有各种各样的疑问和问题。在上一篇中,我们完成了表单的基础搭建和提交。现在,在这篇指南中,我们将使用一些高级技巧,进一步提升表单的功能和用户体验,包括 Form.List、getFieldDecorator、验证和自定义组件。让我们开始吧!

深入Form.List

在之前的文章中,我们已经了解到 Form.List 可以让我们轻松地处理表单数组,但是在实际应用中,可能需要对 Form.List 进行更多的自定义。

使用 render 函数

Form.List 最强大的特性之一是它允许您使用 render 函数来完全自定义列表项的渲染方式。这可以实现非常复杂的表单布局和交互。

const CustomizedForm = Form.create({
  render() {
    const { getFieldDecorator } = this.props;
    return (
      <Form layout="horizontal">
        <Form.List name="tags">
          {(fields, { add, remove }) => {
            return (
              <>
                {fields.map((field, index) => (
                  <Form.Item label={`标签 ${index + 1}`} key={field.key}>
                    {getFieldDecorator(field.name, {
                      rules: [{ required: true, message: '请填写标签' }],
                    })(<Input placeholder="标签" />)}
                    <Icon
                      className="dynamic-delete-button"
                      type="minus-circle-o"
                      onClick={() => remove(field.name)}
                    />
                  </Form.Item>
                ))}
                <Form.Item>
                  <Button
                    type="dashed"
                    onClick={() => add()}
                    style={{ width: '60%' }}
                  >
                    <Icon type="plus" /> 添加标签
                  </Button>
                </Form.Item>
              </>
            );
          }}
        </Form.List>
        <Form.Item>
          <Button type="primary" htmlType="submit">
            提交
          </Button>
        </Form.Item>
      </Form>
    );
  },
});

巧用 getFieldDecorator

getFieldDecorator 是一个非常强大的工具,它允许我们对表单字段进行各种操作,包括:

设置初始值

const WrappedForm = Form.create()(MyForm);

class MyForm extends React.Component {
  componentDidMount() {
    const { setFieldsValue } = this.props.form;
    setFieldsValue({
      username: 'admin',
      age: 20,
    });
  }

  render() {
    const { getFieldDecorator } = this.props.form;
    return (
      <Form>
        <Form.Item label="用户名">
          {getFieldDecorator('username')(
            <Input placeholder="请输入用户名" />
          )}
        </Form.Item>
        <Form.Item label="年龄">
          {getFieldDecorator('age')(
            <Input placeholder="请输入年龄" />
          )}
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit">
            提交
          </Button>
        </Form.Item>
      </Form>
    );
  }
}

设置规则

const WrappedForm = Form.create({
  mapPropsToFields(props) {
    return {
      username: Form.createFormField({
        ...props.username,
        value: props.username.value || '',
        rules: [
          { required: true, message: '请输入用户名' },
          { min: 4, message: '用户名至少需要 4 个字符' },
        ],
      }),
      age: Form.createFormField({
        ...props.age,
        value: props.age.value || '',
        rules: [{ required: true, message: '请输入年龄' }],
      }),
    };
  },
})(MyForm);

灵活的验证

在前面的章节中,我们已经介绍了如何使用 Antd4 的内置验证规则。但有时候,我们需要更灵活的验证规则,比如:

自定义验证规则

const WrappedForm = Form.create({
  mapPropsToFields(props) {
    return {
      username: Form.createFormField({
        ...props.username,
        value: props.username.value || '',
        rules: [
          { required: true, message: '请输入用户名' },
          { validator: (rule, value, callback) => {
            if (value.length < 4) {
              callback('用户名至少需要 4 个字符');
            } else {
              callback();
            }
          } },
        ],
      }),
    };
  },
})(MyForm);

异步验证

const WrappedForm = Form.create({
  mapPropsToFields(props) {
    return {
      username: Form.createFormField({
        ...props.username,
        value: props.username.value || '',
        rules: [
          { required: true, message: '请输入用户名' },
          {
            validator: (rule, value, callback) => {
              setTimeout(() => {
                if (value === 'admin') {
                  callback('用户名已存在');
                } else {
                  callback();
                }
              }, 1000);
            },
          },
        ],
      }),
    };
  },
})(MyForm);

自定义组件的集成

Antd4 提供了强大的扩展性,允许我们轻松集成自定义组件。这使得我们可以构建出更加个性化和功能丰富的表单。

集成自定义组件

const MyInput = (props) => {
  const { getFieldDecorator } = props.form;
  return (
    <Form.Item>
      {getFieldDecorator('username', {
        rules: [{ required: true, message: '请输入用户名' }],
      })(<Input placeholder="请输入用户名" />)}
    </Form.Item>
  );
};

const WrappedForm = Form.create()(MyInput);

至此,我们已经完成了 Antd4 Form 的深入探索。通过这系列文章,您已经掌握了如何使用 Antd4 Form 构建各种复杂的表单。希望这些技巧能够帮助您在实际项目中游刃有余地使用 Antd4 Form。