随着element ui的使用,很多业务场景的实现,往往需要多个组件嵌套使用来实现;
前段时间,为了实现表格中的每一行的数据进行校验的同时实现添加多个的需求;
初步想法
在每一行对应属性中嵌套表单实现逐个校验;但是由于数据量大大;一行需要展示的属性很多;以至于不得不使用表格的fixed属性,这样导致的问题:添加多条数据点击确认时,控制台有警告;但是页面上需要展示的提示信息,始终没有显示;查阅很多资料,有关fixed引起的错位等等;尝试很多,始终没有找到解决方式,有相关经验的,还请赐教?
替代方式
和之前不同的,这次使用表单嵌套表格的形式
要点
1.表格数据datas必须是某对象(以form为例)的一个属性
form: {
datas: [
{ id: 1, name: "ll", age:20 },
{ id: 2, name: "zz", age:32 },
],
},
2.每个字段要动态绑定表单的prop属性(以name字段为例)
<el-form :model="form" :rules="rules" ref="form">
<el-form-item :prop="'datas.'+scope.$index + '.name'" :rules='rules.name'>
</el-form>
注意::prop="'datas.'+scope.$index + '.name'"
,这是elementui规定的格式,渲染后的结果为’datas.1.name’。所以必须结合第1点才能实现,否则提示出错!
3.每个字段要动态绑定表单的rules属性
<el-form-item :prop="‘datas.’+scope.$index + ‘.name’"
:rules='rules.name'
>
4.针对某一行的所有字段进行校验
4.1每一行对应有添加,编辑,重置等操作
表单的字段对象存在this.$refs[‘form’].fields里面,并且字段对象具有prop属性(’datas.1.name’)和validateField方法(验证’datas.1.name’能否通过校验)。
那么我们创建一个函数validateField,来判断第index行的所有字段能否通过校验
//对部分表单字段进行校验
validateField(form,index){
let result = true;
for (let item of this.$refs[form].fields) {
if(item.prop.split(".")[1] == index){
this.$refs[form].validateField(item.prop,(error)=>{
if(error!=""){
result = false;
}
});
}
if(!result) break;
}
return result;
},
4.2 重置
表单的字段对象存在resetField方法来重置数据
,那么我们创建一个函数 resetField,来重置第index行的所有字段
//对部分表单字段进行重置
resetField(form,index){
this.$refs[form].fields.forEach(item=>{
if(item.prop.split(".")[1] == index){
item.resetField();
}
})
},
4.3 添加多个时
只需要对整个表单进行校验即可实现多行校验的呈现结果,调用validate方法
let flag = null
this.$refs.form.validate(valid => {
if (valid) {
flag = valid
} else {
console.log('error submit!!')
return false
}
})
//flag满足条件的话,进行调用接口的操作
5.代码参考
<el-form :model="form" :rules="rules" ref="form">
<el-table :data="form.datas" highlight-current-row style="width: 100%">
<el-table-column prop="id" label="序号" width="60"></el-table-column>
<el-table-column prop="name" label="姓名">
<template slot-scope="scope">
<template v-if="scope.row.action == 'view'">
{{scope.row.name}}
</template>
<template v-else>
<el-form-item :prop="'datas.'+scope.$index + '.name'" :rules='rules.name'>
<el-input size="mini" v-model.trim="scope.row.name" style="width:120px;">
</el-input>
</el-form-item>
</template>
</template>
</el-table-column>
</el-table>
</form>
//表单验证规则
rules: {
name: [{
type: 'string',
required: true,
trigger: 'blur',
message: '请输入姓名',
}],
age: [{
type: 'number',
required: true,
trigger: 'blur',
message: '请输入年龄',
},
{
type: 'number',
trigger: 'blur',
min: 0,
max: 120,
message: '年龄最小0,最大120',
}],
}
}
},
6.场景实现