el-form 表单校验 异步问题 解决
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了el-form 表单校验 异步问题 解决相关的知识,希望对你有一定的参考价值。
参考技术A 问题描述:
一个新增页面里有多个组件,在新增页面对组件进行 校验 必填项等,发现效验有异步问题;
之前写法
异步原因:表单中有级联,下拉框等,是需要调接口的,需要时间,就会异步;
解决问题方法:使用 Promise
动态生成的表单如何用 el-form 校验,你知道吗?
背景
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 属性,如何进行校验
以上是关于el-form 表单校验 异步问题 解决的主要内容,如果未能解决你的问题,请参考以下文章