antd pro form 数组套数组 form数组动态赋值 shouldUpdate 使用

antd form中数组套数组

form数组动态变化 动态赋值

需求如上,同时添加多个产品,同时每个产品可以增加多台设备,根据设备增加相应编号,所以存在数组套数组,根据数组值动态变化
使用的知识点

  1. form.list form中的数组展示
  2. shouldUpdate 根据form值来动态变化
  3. 数组是引用类型
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>

使用注意

  1. Form.List 使用 {...field}或者{...tlist} 需要在name的前面,否则出错
  2. 中间有关于业务的逻辑,输入数量的计算
  3. shouldUpdate 方法使用,表单中值变化,可以根据index来获取是第几个,进而判断
  4. form数组的嵌套 运用两个form.list 嵌套,重点关注内层的 name 怎么写,进而进行内部的循环
  5. 在对form 的数组进行赋值的操作时 紧记 数组是引用类型 ,用getFieldsValue 来获取需要操作的数组,运用数组中的修改原数组 的方法来操作,即可及时修改form值
    数组是引用类型
    数组是引用类型
    数组是引用类型

以上为代码和理解,欢迎指正

相关推荐
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
林太白8 小时前
❤React-React 组件通讯
前端·javascript·react.js
豆华8 小时前
React 中 为什么多个 JSX 标签需要被一个父元素包裹?
前端·react.js·前端框架
前端熊猫8 小时前
React第一个项目
前端·javascript·react.js
练习两年半的工程师8 小时前
使用React和Vite构建一个AirBnb Experiences克隆网站
前端·react.js·前端框架
林太白8 小时前
❤React-JSX语法认识和使用
前端·react.js·前端框架
女生也可以敲代码8 小时前
react中如何在一张图片上加一个灰色蒙层,并添加事件?
前端·react.js·前端框架
布兰妮甜9 小时前
前端框架大比拼:React.js, Vue.js 及 Angular 的优势与适用场景探讨
前端·vue.js·react.js·前端框架·angular.js
老码沉思录10 小时前
React Native 全栈开发实战班 - 核心组件与导航
javascript·react native·react.js