一、需求
当需要给用户填写表格时,并且用户填写行数未知,需要使用到动态表单功能,这个和通常的写死form表单不同,如下图所示:
二、实现
1、前端代码如下图所示:采用el-form嵌套el-table的方法,整体结构如下图所示:
<el-form :model="instance.items" ref="data" label-width="auto">
<el-table
:data="instance.items.filter((data) => handleAdd)"
tooltip-effect="dark"
size="small"
ref="table"
>
<template>
<el-table-column label="人员" align="center" width="420px">
<template slot-scope="scope">
<el-form-item
:prop="scope.$index + '.checkedPersons'"
:rules="{
required: true,
message: '至少要选择一个人员',
trigger: 'change',
}"
>
<el-checkbox-group
v-model="instance.items[scope.$index].checkedPersons"
>
<el-checkbox
v-for="name in xxxPersons"
:label="name"
:key="name"
>{{ name }}</el-checkbox
>
</el-checkbox-group>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="时间" align="center">
<template slot-scope="scope">
<el-form-item
:prop="scope.$index + '.time'"
:rules="rules.requireTime"
>
<el-date-picker
v-model="instance.items[scope.$index].time"
placeholder="请选择"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
style="width: 100%"
type="date"
></el-date-picker>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="备注" align="center">
<template slot-scope="scope">
<el-form-item
:prop="scope.$index + '.remark'"
:rules="{
required: true,
message: '备注不能为空',
trigger: 'blur',
}"
>
<el-input
v-model="instance.items[scope.$index].remark"
type="textarea"
:autosize="{ minRows: 5, maxRows: 10 }"
maxlength="256"
></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="要求" align="center">
<template slot-scope="scope">
<el-form-item
:prop="scope.$index + '.require'"
:rules="{
required: true,
message: '要求不能为空',
trigger: 'blur',
}"
>
<el-input
v-model="instance.items[scope.$index].require"
type="textarea"
:autosize="{ minRows: 5, maxRows: 10 }"
maxlength="256"
></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="备注2" align="center">
<template slot-scope="scope">
<el-form-item
:prop="scope.$index + '.remark2'"
:rules="{
required: true,
message: '备注2不能为空',
trigger: 'blur',
}"
>
<el-input
v-model="instance.items[scope.$index].remark2"
type="textarea"
:autosize="{ minRows: 5, maxRows: 10 }"
maxlength="256"
></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
@click="handleDelete(scope.$index)"
type="text"
size="small"
>移除</el-button
>
</template>
</el-table-column>
</template>
</el-table>
</el-form>
2、添加删除行,以对象的形式添加和删除即可
// 添加行
handleAdd() {
let row = {
name: '',
checkedPersons: [],
time: '',
remark: '',
require: '',
remark2: ''
}
this.instance.items.push(row);
},
handleDelete(index) {
this.instance.items.splice(index, 1);
},
3、添加校验规则,当时实现这个功能,因为对elementUI还不够熟悉,添加校验规则花了挺长时间。规则可以直接绑定到form上,也可以写到js脚本上。
<el-form-item
:prop="scope.$index + '.checkedPersons'"
:rules="{
required: true,
message: '至少要选择一个人员',
trigger: 'change',
}"
>
这个当时卡了比较久,prop的数值绑定我一直参考v-model,加了个instance导致数据一直无法绑定,只需加个索引即可。
如果rules里面涉及到一些参数比较等自定义的规则,就需要把规则写道js里面
<el-form-item
:prop="scope.$index + '.time'"
:rules="rules.requireTime"
>
js规则代码如下所示:
rules: {
requireTime: [
{ required: true, message: '请输入要求时间', trigger: 'blur' },
{
validator: (rule, value, callback) => {
var inputTime = value;
let requireTime = this.item.requestTime;
//用户输入的时间大于要求时间
if (inputTime > requireTime) {
callback(new Error('不能大于要求时间'));
}
callback();
},
trigger: "blur"
}
],
},
以上就是实现动态表单的方法。