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包裹,导致表单无法收集它的值。需要调整结构,让每个动态表单项对应一个包含前置操作符和输入值的对象,具体修改如下:
- 把
Input的addonBefore里的Select用Form.Item包裹,设置name="prefix"并标记noStyle,让它融入当前的表单项结构中。 - 原来的
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
相关产品推荐
相关产品推荐

