You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ant Design动态表单:如何让前置标签数据在onFinish中返回?

问题描述

使用Ant Design构建动态表单,每个表单项包含带前置标签(Select组件)的输入框,已实现动态添加/删除表单项及前置标签展示,但前置标签的选中值无法在onFinish()方法中被获取到。

原代码

JavaScript部分

"use strict";
const { createRoot } = ReactDOM;
const { MinusCircleOutlined, PlusOutlined } = icons;
const { Button, Form, Input, Select } = antd;
const App = () => {
    const onFinish = (values) => {
        console.log("Received values of form:", values);
    };
    return (React.createElement(Form, { name: "dynamic_form_item", onFinish: onFinish, style: {
            maxWidth: 600
        } },
        React.createElement(Form.List, { name: "names" }, (fields, { add, remove }, { errors }) => (React.createElement(React.Fragment, null,
            fields.map((field, index) => (React.createElement(Form.Item, { required: false, key: field.key },
                React.createElement(Form.Item, Object.assign({}, field, { rules: [
                        {
                            required: true,
                            whitespace: true,
                            message: "Please input a filter or delete this field."
                        }
                    ], noStyle: true }),
                    React.createElement(Input, { placeholder: "filter", addonBefore: 
                        //<Form.Item name="prefix" noStyle>
                        React.createElement(Select, { popupMatchSelectWidth: false, listHeight: 1000, defaultValue: "LIKE", options: [
                                { label: "LIKE", value: "LIKE" },
                                { label: "NOT LIKE", value: "NOT LIKE" },
                                { label: "=", value: "=" },
                                { label: "!=", value: "!=" },
                                { label: "BETWEEN", value: "BETWEEN" },
                                { label: ">", value: ">" },
                                { label: "<", value: "<" },
                                { label: ">=", value: ">=" },
                                { label: "<=", value: "<=" }
                            ] }) })),
                React.createElement(MinusCircleOutlined, { onClick: () => remove(field.name) })))),
            React.createElement(Form.Item, null,
                React.createElement(Button, { onClick: () => add(), icon: React.createElement(PlusOutlined, null) }, "Add field"),
                React.createElement(Form.ErrorList, { errors: errors }))))),
        React.createElement(Form.Item, null,
            React.createElement(Button, { type: "primary", htmlType: "submit" }, "Submit"))));
};
const ComponentDemo = App;
createRoot(mountNode).render(React.createElement(ComponentDemo, null));

HTML部分

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>CodePen - Dynamic Form Item - antd@5.11.5</title>

</head>
<body>
<!-- partial:index.partial.html -->
<!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width">
          <meta name="theme-color" content="#000000">
        </head>
        <body>
          <div id="container" style="padding: 24px" />
          <script>const mountNode = document.getElementById('container');</script>
        </body>
      </html>
<!-- partial -->
  <script src='https://unpkg.com/react@18/umd/react.development.js'></script>
<script src='https://unpkg.com/react-dom@18/umd/react-dom.development.js'></script>
<script src='https://unpkg.com/dayjs@1/dayjs.min.js'></script>
<script src='https://unpkg.com/antd@5.11.5/dist/antd-with-locales.min.js'></script>
<script src='https://unpkg.com/@ant-design/icons/dist/index.umd.js'></script>
<script src='https://unpkg.com/react-router-dom/dist/umd/react-router-dom.production.min.js'></script>
<script src='https://unpkg.com/react-router/dist/umd/react-router.production.min.js'></script><script  src="./script.js"></script>

</body>
</html>
解决方案

问题出在前置的Select组件没有被Form.Item包裹,导致表单无法收集它的值。需要调整结构,让每个动态表单项对应一个包含前置操作符和输入值的对象,具体修改如下:

  1. 把Input的addonBefore里的Select用Form.Item包裹,设置name="prefix"并标记noStyle,让它融入当前的表单项结构中。
  2. 原来的Input对应的Form.Item需要调整name为"value",这样每个动态项会生成{ prefix: 'xxx', value: 'xxx' }的结构,被表单正确收集。

修改后的核心代码片段:

fields.map((field, index) => (
  React.createElement(Form.Item, { required: false, key: field.key },
    // 包裹操作符Select的Form.Item
    React.createElement(Form.Item, {
      ...field,
      name: [field.name, 'prefix'], // 对应对象的prefix属性
      noStyle: true
    },
      React.createElement(Select, {
        popupMatchSelectWidth: false,
        listHeight: 1000,
        defaultValue: "LIKE",
        options: [
          { label: "LIKE", value: "LIKE" },
          { label: "NOT LIKE", value: "NOT LIKE" },
          { label: "=", value: "=" },
          { label: "!=", value: "!=" },
          { label: "BETWEEN", value: "BETWEEN" },
          { label: ">", value: ">" },
          { label: "<", value: "<" },
          { label: ">=", value: ">=" },
          { label: "<=", value: "<=" }
        ]
      })
    ),
    // 包裹输入框的Form.Item
    React.createElement(Form.Item, {
      ...field,
      name: [field.name, 'value'], // 对应对象的value属性
      rules: [
        {
          required: true,
          whitespace: true,
          message: "Please input a filter or delete this field."
        }
      ],
      noStyle: true
    },
      React.createElement(Input, { placeholder: "filter" })
    ),
    React.createElement(MinusCircleOutlined, { onClick: () => remove(field.name) })
  )
))

修改后,onFinish中拿到的values.names会是一个数组,每个元素是{ prefix: '选中的操作符', value: '输入的内容' }的对象,这样就能正确获取前置标签的数据了。

内容的提问来源于stack exchange,提问作者user22009348

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:47:10