龙空技术网

动态生成的表单如何用 el-form 校验,你知道吗?

毕小宝 338

前言:

而今各位老铁们对“表单校验trigger”可能比较注意,大家都想要学习一些“表单校验trigger”的相关文章。那么小编也在网络上搜集了一些有关“表单校验trigger””的相关资讯,希望各位老铁们能喜欢,大家一起来学习一下吧!

背景

Vue 的 el-form 提供了表单校验功能,常规用法是用 :rules 属性设置校验规则,并通过 el-form-item 的 prop 属性绑定校验规则。但是有一种情况,如果表单位于 v-for 标签中,是动态生成的,该怎么使用 el-form-item 来校验呢?

此外,如果待校验的表单是 el-popover 组件中的 readonly 表单,blur 触发不稳定,该怎么处理呢?

本文继续分享这两个问题的解决办法。

v-for 遍历的表单校验

根据官网的介绍,是在 el-form-item 中使用 :rules 属性,同时 prop 属性直接定位到具体循环元素。这个用法的前提是在循环外面包裹一个 el-form 元素,v-for 位于 el-form-item 中。

<el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic">  <el-form-item prop="email"  label="邮箱"  :rules="[      { required: true, message: '请输入邮箱地址', trigger: 'blur' },      { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }    ]"  >    <el-input v-model="dynamicValidateForm.email"></el-input>  </el-form-item>  <el-form-item    v-for="(domain, index) in dynamicValidateForm.domains"    :label="'域名' + index"    :key="domain.key"    :prop="'domains.' + index + '.value'"    :rules="{      required: true, message: '域名不能为空', trigger: 'blur'    }"  >    <el-input v-model="domain.value"></el-input><el-button @click.prevent="removeDomain(domain)">删除</el-button>  </el-form-item>  <el-form-item>    <el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</el-button>    <el-button @click="addDomain">新增域名</el-button>    <el-button @click="resetForm('dynamicValidateForm')">重置</el-button>  </el-form-item></el-form>

位于循环中的 el-form-item ,为 el-form-item 设置 :rules 属性,同时设置它的 prop 属性需要遵循的规则为:

   prop=循环对象.下标.子属性

运行效果:

通过反复测试,我发现了一种更简单的方法,就是 v-for 针对 el-from ,每个循环的本质就是一次独立的 el-form 校验,这就跟普通表单的校验没啥区别了,容易写也好理解。

循环内部创建 el-form 表单校验

这种方法是在 v-for 语句内部,循环创建 el-form 表单,它的 modle 指向当前循环的元素,它内部的 el-form-item 直接引用当前循环元素的子属性即可。

例如,下面这个功能配置页面,每个规则包含三项信息名称、分类、相关字段:

校验时,将每个规则的配置信息包裹在一个 el-form 中,就跟普通表单校验一样。

首先,定义 rules 对象:

rules1: {        name: [          { required: true, message: '请输入业务名称', trigger: 'blur' },        ],        typeName: [          { required: true, message: '请选择分类', trigger: 'change' },        ],        relation: [          { required: true, message: '请选择字段', trigger: ['blur', 'change'] },        ],      },

接着,编写 el-form 和 el-form-item ,设置校验属性:

<el-row  :key="index"   v-for="(item,index) in data.rules">   <el-col :span="20" >	<el-form  :model="item"  :rules="rules1" :ref="`ruleForm${index}`">	  <el-form-item label="业务名称:" prop="name"   >	    <el-input clearable v-model="item.name"/>	  </el-form-item>	  <el-form-item label="所属分类:" prop="typeName"  >	    <el-popover  rigger="click" placement="bottom">		<el-tree		  :ref="`tree${index}`"		  :data="typeInfos"		  node-key="name"		  :current-node-key="item.typeName"		  :props="defaultProps"		  :filter-node-method="filterNode"		  @node-click="changeFieldSelector(index)">		</el-tree>	      <el-input v-model="item.typeName" readonly placeholder="选择分类" >	      </el-input>	    </el-popover>	  </el-form-item>	  <el-form-item  prop="relation" label="相关字段:"  :label-width="formLabelWidth">	    <el-select clearable v-model="item.relation " placeholder="选择字段">	    </el-select>	  </el-form-item>	</el-form>                   <i class="el-icon-circle-plus-outline"   @click="addRule(index)"/>      <i class="el-icon-circle-close"   @click="deleteRule(index)"/>    </el-col>  </el-row>

核心思路是,在每一轮 v-for 中,创建 el-form ,model 指向的是 v-for 的迭代元素 item:

v-for="(item,index) in data.rules"内部引用迭代对象: el-form :model=“item” :rules=“rules1”el-from-item 正常引用 item 的属性:

最后,保存时循环触发各个 el-form 的校验:

 // 触发各部分的表单的校验操作 for (let i = 0; i < this.data.rules.length; i += 1) {   this.$refs[`ruleForm${i}`][0].validate((valid) => {     if (!valid) {       isOk = false;       return false;     }     return true;   }); }
prop 属性指定异常

循环内部指定 prop 时,容易出现这个异常:

也就是说 el-form-item上的属性 prop字段,必须是其父级组件 el-form 中绑定 model 字段的直接子属性。

所以,用官网推荐的循环的方式,必须小心 prop 赋值,保证每个 el-form-item 的 prop 与 rules 对象中的属性一致。

校验表单位于 el-popover 中

如果校验的表单是 el-popover 弹出选项的 readonly 表单,该怎么校验呢?

前面例子中的第二个表单 “所属分类” 是一个弹出树选择组件,选中树节点后将值绑定到一个 readonly 表单,这个表单才是我们要验证的。这时存在一种问题:这个只读组件的 onblur 触发校验后,即使通过弹框选择了元素,错误信息还是无法消失。

为了解决这个问题,可以在 el-tree 的选中事件中手动触发一次校验:

changeFieldSelector(index) { // 数据名称树节点选中时触发的方法      const tree = this.$refs[`tree${index}`];      // 因为 el-tree 是在 v-for 中,VUE 用了数组存储,所以需要再取【0】得到 el-tree 对象      const data = tree[0].currentNode.node.data;      console.log(`点击了第${index + 1}个节点的日志类型,选中的类型是 ${data.name}`);      Vue.set(rule, 'typeName', data.typeName);      Vue.set(rule, 'type', data.type);      // 手动触发 readonly 表单校验      this.$refs[`ruleForm${index}`][0].validate((valid) => {        if (!valid) {          return false;        }        return true;      });    },
启示录

文本介绍了三个表单校验的问题,补充上一节的内容,比官网的介绍都还要完整

v-for 动态生成的表单校验,如何校验please transfer a valid prop path to form item 属性绑定问题;位于 el-popover 中的 readonly 属性,如何进行校验

标签: #表单校验trigger