在el-form 中,对动态增加的表单项进行必填验证功能

114 阅读1分钟

在实际开发业务场景中,经常会在el-form中遇到动态增加表单项的场景,对这种动态产生的表单项进行验证

image.png

1,是对列表父级表单进行验证

formData: {
    scoreList: [
      {
        skill: undefined,
        score: undefined,
      }
    ]
 }

<el-form-item label="动态表单" prop="scoreList">
          <el-row class="score-row" v-for="(item,index) in formData.scoreList" :key="index" :gutter="10">
            <el-col :span="12">
              <el-form-item >
                <el-select v-model="item.skill" style="width: 100%" placeholder="请选择能力">
                  <el-option
                    v-for="item in skillOptions"
                    :key="item.id"
                    :label="item.skillName"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item >
                <el-input v-model="item.score" placeholder="请输入最高分数"/>
              </el-form-item>
            </el-col>
            <el-col :span="2" :offset="1">
              <i class="el-icon-delete" @click="formData.scoreList.splice(index,1)"/>
            </el-col>
          </el-row>
          <div class="add-row" @click="addScore">
            <i class="el-icon-circle-plus-outline"></i> 点击继续添加
          </div>
        </el-form-item>
        
        //自定义验证
      formRules: {
        scoreList: [
          { required: true, validator: checkScoreList, trigger: 'blur' }
        ],
      },
      
      const checklist =  (rule, value, callback) => {
                let bool = this.formData.scoreList.some(e => !e.skill || !e.score)
                if (bool) {
                        return callback(new Error('请填写完成打分项'));
                } else {
                        callback()
                }
        }

这种会在父表单项最下面提示验证,但是有个缺点是有某个子表单没有验证通过会把父表单下所有的表单都高亮预警,包括已经填写完成的

image.png

我尝试用this.$refs.FormRef.getFieldsError(true),获取高亮的dom元素然后去遍历移除有数据的报警表单的error-row类,但是会报TypeError: this.$refs.formRef.getFieldsError is not a function,最终没能实现, 这种验证显然不太完美,最好是精确到每一个表单所以后面又用了第二种方式。

2,为动态增加到每个表单项添加验证

<el-form-item label="动态表单" required>
  <el-row class="score-row" v-for="(item,index) in formData.scoreList" :key="index" :gutter="10">
    <el-col :span="12">
      <el-form-item :prop="`scoreList.${index}.skill`" :rules="{ required: true, message: '请选择能力', trigger: 'blur' }">
        <el-select v-model="item.skillIds" style="width: 100%" placeholder="请选择能力">
          <el-option
            v-for="item in skillOptions"
            :key="item.id"
            :label="item.skillName"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
    </el-col>
    <el-col :span="8">
      <el-form-item :prop="`scoreList.${index}.score`" :rules="{ required: true, message: '请输入最高分数', trigger: 'blur' }">
        <el-input v-model="item.score" placeholder="请输入最高分数"/>
      </el-form-item>
    </el-col>
    <el-col :span="2" :offset="1">
      <i class="el-icon-delete" @click="formData.scoreList.splice(index,1)"/>
    </el-col>
  </el-row>
  <div class="add-row" @click="addScore">
    <i class="el-icon-circle-plus-outline"></i> 点击继续添加
  </div>
</el-form-item>

这里父级表单别忘了加上required,为了展示必填的*号,下面看下效果

image.png

这里要说的是rule验证一定要加在动态子表单标签上,加在form层的rule的对象上是没有效果的! 当然动态添加表单时也是要加验证的,最后一行表单项如果有没有填写完不让继续添加,这个比较简单我就不贴代码了。