antd form中数组套数组
form数组动态变化 动态赋值
需求如上,同时添加多个产品,同时每个产品可以增加多台设备,根据设备增加相应编号,所以存在数组套数组,根据数组值动态变化
使用的知识点
- form.list form中的数组展示
- shouldUpdate 根据form值来动态变化
- 数组是引用类型
javascript
// An highlighted block
<div >
<Form
form={form}
name="basic"
labelCol={{
flex: '90px',
}}
initialValues={{
productList:[{
bianHao:'',
wuMiao:'',
number:1,
tType:'you',
files:{},
list:[{
sheBei:'',
guZi:'',
ziYou:'',
}],
}]
}}
labelWrap={true}
labelAlign="left"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
{/* <Card
title="基本信息"
bordered={false}>
<Row gutter={16}>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
label="最终用户"
name="username"
rules={[
{
required: true,
message: '请输入',
},]}
>
<Input />
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
label="商务助理"
name="userLian"
rules={[
{
required: true,
message: '请输入',
},]}
>
<Input />
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
label="测试用途"
name="userPhone"
rules={[
{
required: true,
message: '请输入',
},]}
>
<Input />
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
label="项目预计招标/采购时间"
name="userShou"
rules={[
{
required: true,
message: '请输入',
},]}
>
<Input />
</Form.Item>
</Col>
<Col sm={24} >
<Form.Item
label="备注"
name="beiZhu"
rules={[{
required: true,
message: '请输入',
},]}
>
<TextArea />
</Form.Item>
</Col>
<Col xl={24} sm={24}>
<Form.Item label='证明文件' >
<Upload {...fileProps}>
<Button type="primary" icon={<UploadOutlined />}>点击上传</Button>
</Upload>
</Form.Item>
</Col>
</Row>
</Card> */}
<Card
title="基本信息"
bordered={false}>
<Form.List name="productList" >
{(fields, {add, remove}) => (
<>
{fields.map((field,index) => (
<Row gutter={16}>
{/* 用得时候只需要修改下面,将需要重复展示的部分替换下面部分即可 注意 -----start*/ }
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...field}
label="产品名称"
name={[field.name,"bianHao"]}
rules={[{
required: true,
message: '请输入',
},]}
>
<Input placeholder="请输入" />
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...field}
label="物料编码"
name={[field.name,"wuMiao"]}
rules={[{
required: true,
message: '请输入',
},]}
>
<Input placeholder="请输入" />
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...field}
label="数量"
name={[field.name,"number"]}
rules={[{
required: true,
message: '请输入',
},]}
>
<InputNumber min={1} style={{width:'100%'}}/>
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...field}
label="单位"
name={[field.name,"tType"]}
rules={[{
required: true,
message: '请输入',
},]}
>
<Select>
<Select.Option value="you">台</Select.Option>
<Select.Option value="zi">块</Select.Option>
</Select>
</Form.Item>
</Col>
<Col sm={24}>
<Form.Item noStyle shouldUpdate={(pre,cur) => {
// 如果删除一条信息,cur.productList[index]是空值,所以需要判断
if(cur.productList[index]&&pre.productList[index]){
return pre.productList[index].number !== cur.productList[index].number
}else{
return false
}
}}>
{
({getFieldsValue}) =>{
{/* 繁琐的计算:1.输入的数值比原来的数值大,计算差值,给原数组循环push
2.手动在删除,输入框为空的时候,根据splice置空 (因为是空,所以计算出0)
3.输入的数值比之前小,优先从后面删除,防止前面输入的被删除掉,依旧是操作原数组 splice */}
let number = getFieldsValue().productList[index].number;
let list = getFieldsValue().productList[index].list;
if(number>list.length){
let cha = number - list.length;
for(let i=0; i<cha ; i++){
list.push({ sheBei:'',
guZi:'',
ziYou:'',})
}
}else if(number===''){
list.splice(0,list.length)
}else if(number<list.length){
let cha = list.length - number;
list.splice(number,cha)
}
return <Form.List name={[field.name,"list"]} >
{(tLists) => (
<>
{tLists.map(tlist=>(
<Row gutter={16}>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...tlist}
label="设备序列号"
name={[tlist.name,"sheBei"]}
rules={[{
required: true,
message: '请选择',
},]}
>
<Input/>
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...tlist}
label="固资编码"
name={[tlist.name,"guZi"]}
rules={[{
required: true,
message: '请选择',
},]}
>
<Input/>
</Form.Item>
</Col>
<Col sm={24} md={12} lg={8} xxl={6}>
<Form.Item
{...tlist}
label="自有编码"
name={[tlist.name,"ziYou"]}
rules={[{
required: true,
message: '请选择',
},]}
>
<Input/>
</Form.Item>
</Col>
</Row>
))}
</>
)}
</Form.List>
}
}
</Form.Item>
</Col>
<Col sm={24} >
<Form.Item
label="备注"
{...field}
name={[field.name,"beiZhu"]}
rules={[{
required: true,
message: '请输入',
},]}
>
<TextArea />
</Form.Item>
</Col>
<Col xl={24} sm={24}>
<Form.Item
label='证明文件'
{...field}
name={[field.name,"files"]}
>
<Upload
customRequest={(option=> option.onSuccess())}
beforeUpload={(file, fileList)=> fileVerification(file, fileList)}>
<Button type="primary" icon={<UploadOutlined />}>点击上传</Button>
</Upload>
</Form.Item>
</Col>
{ /* 用得时候只需要修改下面,将需要重复展示的部分替换下面部分即可 -----end*/ }
<div styleName="item_btn_wrap">
<PlusCircleFilled styleName="add_item_btn" onClick={() => add({
bianHao:'',
wuMiao:'',
number:1,
tType:'you',
beiZhu:'',
files:{},
list:[{
sheBei:'',
guZi:'',
ziYou:'',
}],
})} />
{fields.length>1&&<CloseCircleFilled styleName="remove_item_btn" onClick={() => remove(field.name)} />}
</div>
</Row>
))}
</>
)}
</Form.List>
</Card>
<Card>
{/* <Row gutter={16}>
<Col> */}
{/* <Form.Item wrapperCol={{ offset: 8, span: 16 }}> */}
<Form.Item styleName="right_layout">
<Link to="/HW/HwBorrowList">
<Button type="dashed">取消</Button>
</Link>
<Button style={{marginLeft:'20px'}} loading={saving} onClick={()=>onFinish('stage')}>暂存</Button>
<Button type="primary" style={{marginLeft:'20px'}} onClick={()=>onFinish('submit')}>提交</Button>
{/* <Button type="primary" htmlType="submit">确认</Button> */}
</Form.Item>
{/* </Col>
</Row> */}
</Card>
</Form>
</div>
使用注意
- Form.List 使用 {...field}或者{...tlist} 需要在name的前面,否则出错
- 中间有关于业务的逻辑,输入数量的计算
- shouldUpdate 方法使用,表单中值变化,可以根据index来获取是第几个,进而判断
- form数组的嵌套 运用两个form.list 嵌套,重点关注内层的 name 怎么写,进而进行内部的循环
- 在对form 的数组进行赋值的操作时 紧记 数组是引用类型 ,用getFieldsValue 来获取需要操作的数组,运用数组中的修改原数组 的方法来操作,即可及时修改form值
数组是引用类型
数组是引用类型
数组是引用类型
以上为代码和理解,欢迎指正