目标效果:
需求分解:
1. 可通过输入框右侧图标动态新增或移除表单项
2. 单独设置最后行的help和第一行label
3. 每个输入框均有输入校验
需求实现:
使用antd里Form表单的动态增减表单项或动态增减嵌套字段
地址附上:表单 Form - Ant Design
提炼后代码如下:
import React from 'react'
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import { Button, Form, Input } from 'antd'
const App = () => {
const onFinish = (values) => {
console.log('Received values of form:', values)
}
return (
<Form name="dynamic_form_item" onFinish={onFinish}>
<Form.List name="names">
{(fields, { add, remove }, { errors }) => (
<>
{fields.map((field, index) => (
<Form.Item
label={index === 0 ? 'Passengers' : ''}
required={false}
key={field.key}
>
<Form.Item name={field.name} key={field.key}>
<Input />
</Form.Item>
{
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => {
remove(field.name)
}}
/>
}
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
icon={<PlusOutlined />}
>
Add field
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
)
}
export default App
效果如下:
参数介绍:
name="names" 前面name与Form.Item那么功能一致
fields为数组对象
field为对象,其中包含name,key等数据,具体如下:
{ add remove } 为解构出来的函数方法
{ errors } 为解构出来的错误列表,仅限配合 Form.List 的 rules 一同使用
问题及解决:
问题1:
需要一个初始的输入框,以及右侧的图标
将Form.List name="names"中的names修改为所使用的数据源(渲染数组),即:
<Form.List name="names"> // 修改前
<Form.List name="DataArr"> // 修改后
输入框右侧的图标添加
在第一层的Form.Item里面进行添加,若是数据回显出现问题,请检查嵌套结构及name属性
tips: 多结构的添加需要以Form.Item来进行嵌套
{(fields, { add, remove }, { errors }) => (
<>
{fields.map((field, index) => (
<Form.Item
label='配置项'
required={false}
key={field.key}
help={
index === fields.length - 1
? LastHelp
: NTPHelp
}
>
<Form.Item
name={field.name}
key={field.key}
>
<Input />
// 此处需要给Input框进行数据回显 由于Form.Item中name属性的限制,图标没有放置一起
</Form.Item>
{
<div>
{index !==
fields.length - 1 && (
<CloseCircleOutlined
onClick={() => {
remove(field.name)
}}
/>
)}
{index ===
fields.length - 1 && (
<PlusCircleOutlined
onClick={() => {
add()
}}
/>
)}
</div>
}
</Form.Item>
))}
</>
)}
问题2
只在最后行设置help
help={
index === fields.length - 1
? LastHelp
: ' '
}
label={
index === 0 ? 'label' : ' ' // 有个空格
}
问题3
每个输入框均有输入校验
在Form.Item里设置rules,即
rules={[
{
required: true,
},
{
pattern: /^[a-zA-Z0-9]{4,32}$/,
},
]}
若是要设置动态help信息,则需使用下面这种校验,原理:利用useState的特性来设置help信息
rules={[
() => ({
validator(_, value) {
if (!reg.test(value)) {
setHelp('定制的help信息')
return Promise.reject(new Error())
}
setHelp('初始help信息') //此处为重置Help, 可为空
return Promise.resolve()
},
}),
]}
// tips: 参数解释
// reg为你的正则
// setHelp为useState
相关代码为
const [Help, setHelp] = useState()
help={Help ||'初始help信息'}
效果如下:
初始状态
校验错误状态1
校验错误状态2