Vue+Element动态生成新表单并添加验证

首先,有这样一个需求,表单中默认有表单项,点击新增,会多出一项。
在这里插入图片描述
点击之后
在这里插入图片描述
官方文档中有写用v-for来实现新增表单,但是那是单表单的新增,现在多表单的新增,可以考虑的实现方法是先写死一个必须的表单,需要新增的两个表单放在一个div里,在div中使用v-for生成,达到同时新增的效果

代码如下

 <div class="item_tit">
                        <i class="tit_shu"></i>
                        <span class="basic_info">工作经历</span>
                        <span class="line_t" style="width:720px;"></span>
                        <span class="addInfo" @click="addDomain">添加 <i class="addimg">+</i></span>
                      </div>

                     <el-row style="margin-top:30px;" class="date_pick">
                        <el-col :span="10" >
                           <el-form-item label="任职时间 "  prop="workTime">
                             <el-date-picker
                                v-model="ruleForm.workTime" value-format="yyyy-MM-dd" type="date" placeholder="请选择您的任职时间">
                             </el-date-picker>
                        </el-form-item>   
                        </el-col>

                         <el-col :span="10" :offset="2" >
                          <el-form-item label="公司名称 "  prop="conpanyName">
                            <el-input v-model="ruleForm.conpanyName" placeholder="请填写公司名称"></el-input>
                          </el-form-item> 
                         </el-col>    
                     </el-row>

                     <el-row  class="date_pick">
                        <el-col :span="10" >
                           <el-form-item label="岗位 "  prop="position">
                            <el-input v-model="ruleForm.position" placeholder="请输入岗位"></el-input>
                           </el-form-item>   
                        </el-col>

                         <el-col :span="10" :offset="2" >
                          <el-form-item label="薪资 "  prop="salary">
                            <el-input v-model="ruleForm.salary" placeholder="请输入薪资"></el-input>
                          </el-form-item> 
                         </el-col>    
                     </el-row>

                      <el-row  class="date_pick">
                        <el-col :span="10" >
                           <el-form-item label="离职原因 "  prop="reason">
                            <el-input v-model="ruleForm.reason" placeholder="请输入离职原因"></el-input>
                           </el-form-item>   
                        </el-col>

                         <el-col :span="10" :offset="2" >
                          <el-form-item label="证明人 "  prop="witness">
                            <el-input v-model="ruleForm.witness" placeholder="请输入证明人姓名"></el-input>
                          </el-form-item> 
                         </el-col>    
                     </el-row>

                     <el-row  class="date_pick">
                        <el-col :span="10">
                           <el-form-item label="联系方式 "  prop="type">
                            <el-input v-model="ruleForm.type" placeholder="请输入证明人联系方式"></el-input>
                           </el-form-item>   
                        </el-col>
                     </el-row>

                     <!-- 新增工作经历 -->
                      <div class="moreRules">
                           <div class="moreRulesIn" v-for="(item, index) in ruleForm.moreNotifyObject" :key="index">
                              <el-row style="margin-top:30px;" class="date_pick">
                                 <el-col :span="10" >
                                 <el-form-item label="任职时间 "  :prop="'moreNotifyObject.' + index +'.workTime'" :rules="moreNotifyOjbectRules.moreNotifyOjbectWorkTime" >
                                    <el-date-picker
                                       v-model="item.workTime" value-format="yyyy-MM-dd" type="date" placeholder="请选择您的任职时间">
                                    </el-date-picker>
                                 </el-form-item>   
                                 </el-col>

                                 <el-col :span="10" :offset="2" >
                                 <el-form-item label="公司名称 "   :prop="'moreNotifyObject.' + index +'.conpanyName'" :rules="moreNotifyOjbectRules.moreNotifyOjbectConpanyName">
                                    <el-input v-model="item.conpanyName" placeholder="请填写公司名称"></el-input>
                                 </el-form-item> 
                                 </el-col>    
                              </el-row>

                              <el-row  class="date_pick">
                                 <el-col :span="10" >
                                    <el-form-item label="岗位 "  :prop="'moreNotifyObject.' + index +'.position'" :rules="moreNotifyOjbectRules.moreNotifyOjbectPosition">
                                    <el-input v-model="item.position" placeholder="请输入岗位"></el-input>
                                    </el-form-item>   
                                 </el-col>

                                 <el-col :span="10" :offset="2" >
                                 <el-form-item label="薪资 " :prop="'moreNotifyObject.' + index +'.salary'"  >
                                    <el-input v-model="item.salary" placeholder="请输入薪资"></el-input>
                                 </el-form-item> 
                                 </el-col>    
                              </el-row>

                              <el-row  class="date_pick">
                                 <el-col :span="10" >
                                    <el-form-item label="离职原因 " :prop="'moreNotifyObject.' + index +'.reason'"  >
                                    <el-input v-model="item.reason" placeholder="请输入离职原因"></el-input>
                                    </el-form-item>   
                                 </el-col>

                                 <el-col :span="10" :offset="2" >
                                 <el-form-item label="证明人 " :prop="'moreNotifyObject.' + index +'.witness'" >
                                    <el-input v-model="item.witness" placeholder="请输入证明人姓名"></el-input>
                                 </el-form-item> 
                                 </el-col>    
                              </el-row>

                              <el-row  class="date_pick">
                                 <el-col :span="10">
                                    <el-form-item label="联系方式 " :prop="'moreNotifyObject.' + index +'.type'" >
                                    <el-input v-model="item.type" placeholder="请输入证明人联系方式"></el-input>
                                    </el-form-item>   
                                 </el-col>
                              </el-row>
                           </div>
                      </div>

和普通表单验证不同的是,动态表单要新增自己的验证规则,和添加普通表单的方式一样

  //普通的校验
  rules :{  
	  name:[ 
	         { required: true, message: '请输入姓名', trigger: 'blur' },
	       ] 
  }
  //新增表单的验证规则
      moreNotifyOjbectRules: {
         moreNotifyOjbectWorkTime: [{ required: true, message: '请选择任职时间', trigger: 'change' },
           
         ],
         moreNotifyOjbectConpanyName: [{ required: true, message: '请输入公司名称', trigger: 'blur' },
            //  { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
         ],
         moreNotifyOjbectPosition: [{ required: true, message: '请输入岗位名称', trigger: 'blur' },
         ],
         },
        }

**加粗样式这里需要注意的是:rules是每个表单都要都要添加的,有多个的话就要给每个表单绑定一个规则
**

  <el-form-item label="任职时间 "  :prop="'moreNotifyObject.' + index +'.workTime'" :rules="moreNotifyOjbectRules.moreNotifyOjbectWorkTime" >
  
 <el-form-item label="公司名称 "   :prop="'moreNotifyObject.' + index +'.conpanyName'" :rules="moreNotifyOjbectRules.moreNotifyOjbectConpanyName">

另外要注意的是:prop,正常表单验证单项是依靠prop,但是动态生成话要用:prop。

*书写的语法是:prop="‘moreNotifyObject.’ + index +’.workTime’",moreNotifyObject是v-for绑定的数组,index是索引,notifyobject是表单绑定的v-model的名称,然后用.把他们链接起来。

所以总结起来的语法就是:prop="‘v-for绑定的数组.’ + index + ‘.v-model绑定的变量’"

还有一个需要注意就是v-for的写法,要将表单的model名写进去

<div class="moreRulesIn" v-for="(item, index) in ruleForm.moreNotifyObject" :key="index">

还有要注意的就是v-for绑定的数组也要在表单的对象里,写在表单对象外是验证不了的,在data里添加

 ruleForm:{
             moreNotifyObject: [{
               workTime: '',
               conpanyName: '',
               position: '',
               salary: '',
               reason: '',
               witness: '',
               type: '',
         
            }],
            moreNotifyObject2: [{
               readTime: '',
               schoolName: '',
               major: '',
               Education: '',
               degree: '',
               fullTime: '',
               other: '',
         
            }],
           option:'', 
           name:'',
           sex:'', 
           date:'',
           age:'', 
           email:'',
           phone:'',
           politics:'',
           place:'',
           marry:'',
           card:'',

然后新增的函数应该这样写

 addDomain(){
        this.ruleForm.moreNotifyObject.push({
               readTime: '',
               schoolName: '',
               major: '',
               Education: '',
               degree: '',
               fullTime: '',
               other: '',
      })
      console.log(this.ruleForm.moreNotifyObject,55)
      },

如果一开始只想让默认必填的表单显示,而新增的不显示,如文章最开头的表现一样,则可以在methods中初始化v-for绑定的数组

methods:{
    //初始化数据
    initData(){
        this.ruleForm.moreNotifyObject = []
    }
},
  created() {
      this.initData()
    }

最后点击保存提交需处理

// 保存提交
      submitForm() {
          console.log(this.ruleForm.moreNotifyObject)
          var arr = []  //工作经历
          var arr2 = [] //教育
          this.ruleForm.moreNotifyObject.forEach((item,index) => {
             arr.push(item)
          })  
          this.ruleForm.moreNotifyObject2.forEach((item,index) => {
             arr2.push(item)
          })
          var obj = {  //教育
             "degree":this.ruleForm.degree, //学位
            "education":this.ruleForm.Education, //学历
            "endTime":'',//结束时间
            "isfullTime":this.ruleForm.fullTime=='0'?'是':'否', //是否全日制
            "other":this.ruleForm.other, //其他
            "professional":this.ruleForm.major, //专业
            "school":this.ruleForm.schoolName, //学校名称
            "startTime":this.ruleForm.readTime //开始时间 
          }
          var obj2 = { //工作
              "certifier":this.ruleForm.witness,//证明人
               "companyName":this.ruleForm.conpanyName,//公司名称
               "contact":this.ruleForm.type,//证明人联系方式
               "dimissionReason":this.ruleForm.reason,//离职原因
               "employmentPeriod":'',//任职期限
               "postName":this.ruleForm.position,//任职岗位
                "employmentPeriodStartTime":this.ruleForm.workTime,
               "salary":this.ruleForm.salary//薪资
          }
          arr.push(obj2) //将表单首先默认的对象push到同一个数组
          arr2.push(obj)
          console.log(arr)
          console.log(arr2)
         this.$refs.ruleForm.validate((valid) => {
              if (valid) {
              let that = this
                  this.$http({
                    method:"post",
                    url:api.submitInterview+'/'+that.interviewId+'/'+that.interviewFormTemplate,
                    headers:headers('application/json;charset=utf-8'),
                    data:{
                    "address":that.ruleForm.CurrentPlace,//现居地址
                     "age":that.ruleForm.age,//年龄
                     "applyPath":that.ruleForm.channel=='1'?'boss直聘':that.ruleForm.channel=='0'?'智联':'51job',//招聘途径
                     "arrivalTime":that.ruleForm.time,//到岗时间
                     "certificate":that.ruleForm.certificate,//获得的证书
                     "computersLevel":that.ruleForm.age,//计算机水平
                     "dateOfBirth":that.ruleForm.date,//生日
                     "desiredIndustry":that.ruleForm.trade,//期望行业
                     "educationDTOList":arr2, //   <====================后台教育是以实体类接收
                     "email":that.ruleForm.email, //邮箱
                     "englishLevel":that.ruleForm.english, //英语水平
                     "expectSalary":that.ruleForm.tradeSalary, //期望薪资
                     "fertility":that.ruleForm.birth=='1'?'已育':'未育',
                     "hobby":that.ruleForm.like, //爱好
                     "idCard":that.ruleForm.card,//身份证
                     "industry":that.ruleForm.industry,  //行业
                     "isRelation":that.ruleForm.relative=='1'?'否':'是',//亲戚关系
                     "marital":that.ruleForm.marry=='1'?'已婚':'未婚',//是否已婚
                     "mobile":that.ruleForm.phone,//电话
                     "name":that.ruleForm.name,//姓名
                     "nativePlace":that.ruleForm.place,//籍贯
                     "nowSalary":that.ruleForm.payment,//当前薪酬
                     "politics":that.ruleForm.politics,//政治面貌
                     "post":that.ruleForm.option,//应聘岗位
                     "sex":that.ruleForm.sex=='1'?'男':'女',
                     "skillLabel":that.ruleForm.skill,//技能标签
                     "wordStatus":that.ruleForm.work=='1'?'在职-月内到岗':that.ruleForm.work=='0'?'离职-随时到岗':that.ruleForm.work=='2'?'在职-考虑机会':'',//目前工作状态
                     "workCity":that.ruleForm.city,//工作城市
                     "workExperienceDTOList":arr//工作 <====================后台是以实体类接收
                  },
                    cache:false
                  }).then(function(res){
                    if(res.data.code==10000 ){
                      that.$message.success(res.data.msg)
                    }else{
                    that.$message.error(res.data.msg);
                    }
                  });
              } else {
                console.log('数据不完整!');
                return false;
              }
          }); 
      },

参考文章

Logo

前往低代码交流专区

更多推荐