对于循环表单,我们可以使用 table 组件来添加其循环表单。那么 form 表单验证和 table 循环组件将怎么联合起来使用校验表单呢?
v-for 是我们用来遍历或者增加多个表单,但是对于 table 组件只需传入 column 和 data 就可以渲染出表格。其实我们将传入的 column 项,添加为 Input、InputNumber、Radio、Checkbox、Select、Cascader、DatePicker、Upload 等表单组件即可。
<el-form
ref="form"
:model="baseForm"
size="mini"
>
<el-table
ref="table"
class="table-list-wrapper export-list"
:data="baseForm.tableData"
:max-height="scrollHeight"
v-loading="loading"
>
<el-table-column fixed type="index" label="#" width="44"/>
<el-table-column prop="transportType" label="运输方式" width="130px">
<template slot-scope="scope">
<el-form-item
:prop="'tableData.' + scope.$index + '.vehicleLength'"
:rules="scope.row.rules.vehicleLength"
>
<!-- 组件 -->
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
我们可以看到,循环表单组件,首先使用 form 表单中加入 table 组件,只不过在 table-column 中添加表单的每一项。我们也可以看到在 rules 是绑定当前行的检验规则,这样设计是为了根据不同的选择动态添加校验规则,注意:校验规则不是一开始就是固定的。可能每一行的数据的校验规则,都是跟这行的数据有关的,因此我将校验规则放在了该行数据的 rules 对象中。
我们将固定的校验规则定义放在一个对象中。同时将动态数据的校验规则放在另一个对象中。
const baseRules = {
transportType: { required: true, message: '请选择运输方式', trigger: 'change' },
......
}
inputRules: {
'HIGHWAY': {
vehicleType: { required: true, message: '请选择车型', trigger: 'change' },
vehicleLength: { required: true, message: '请选择车长', trigger: 'change' },
},
......
},
那么如何动态添加校验规则呢?由于根据不同的值,添加不同的校验规则,举个例子,公里运输就添加车型和车长校验规则,海运则添加箱型校验规则等,根据选择不同的运输方式,我们使用 select 组件的 change 事件对选择的数据进行添加校验规则。
// 修改运输方式
handleTransportType (value, index) {
......
this.baseForm.tableData = this.handleData(this.baseForm.tableData, index)
},
我们可以看到 change 事件中,传入 index 对于 table 中添加 index 行的校验规则。处理如下:
handleData (data, rowIndex) {
return data.map((item, index) => {
item.transportTerms = 'D2D'
// 根据运输方式修改该行校验规则或初始化
if ((rowIndex && rowIndex === index) || !rowIndex) {
item.rules = { ...baseRules, ...this.inputRules[item.transportType] }
}
if (['SEA-CONTAINER'].includes(item.transportType) && ['D2D', 'D2CY'].includes(item.transportTerms)) {
item.rules = { ...item.rules, startPort: { required: true, message: '请选择起运港', trigger: 'change' } }
}
.....
return { ...item }
})
},
删除该行数据,我们需要清空校验规则,同时删除该行数据。
handleDelete (index, row = {}) {
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
this.baseForm.tableData.splice(index, 1)
},
进阶版:
我们如何对循环表单中已勾选的数据进行校验,而未勾选的数据则不进行校验。
未完待续.......