需求描述
1.有一个表格,里面能展示原有数据,同是也能在表格中动态增加一行输入框
2.增加的每个输入框,要动态添加表格的验证,以及表单数据的绑定
3.为了样式统一,使用iview的ui框架
主要难点
- 让表格中同时展示原有数据和新增的输入框
- 新增的输入框,动态绑定表单数据
- 输入框动态增加校验
实现方式
1.使用Table组件,创建表格,绑定好表格列的定义, 使用tableColums变量表示
<Table
:columns="tableColums"
>
</Table>
data中绑定的数据为:
tableColums: [
{
type: 'selection',
width: 40,
align: 'center',
sortable: false
},
{
slot: 'msgType',
title: this.$t('airport.address.rules.msgType'),
minWidth: 10,
align: 'center'
},
{
slot: 'sendWay',
title: this.$t('airport.address.rules.sendWay'),
minWidth: 10,
align: 'center'
},
{
slot: 'detailAddress',
title: this.$t('airport.address.rules.detailAddress'),
minWidth: 10,
align: 'center'
},
{
slot: 'option',
title: this.$t('airport.address.rules.option'),
minWidth: 10,
align: 'center'
}
]
这里全部都使用的slot,是因为表格中需要使用到插槽,来展示输入框
2.使用Form组件,创建提交的表单,将table包裹起来,
因为表格中所有新增的输入框,都需要作为表单数据提交,所以直接使用Form组件包裹起来
<Form>
<Table ...>
....
</Table
</Form>
3.添加表格数据绑定,使其包含在Form表单绑定的数据中
为了减少数据的定义的重复性,这里将表格和表单绑定的数据统一使用一个,也就是tableData。而整个表单数据为formData对象,其中包含tableData。所以并不影响该表单扩展其他需要提交的字段。
<Form :model="formData">
<Table
:columns="tableColums"
:data="formData.tableData"
>
....
</Table
</Form>
data中绑定的数据, 其中如果是新加的就动态添加一个对象,里面包含isNew字段则为新增行
formData:{
tableData: [
{
name: 'xxx',
value: 'dd',
age: 'ddd'
},
{
name: 'xxx',
value: 'dd',
age: 'ddd'
},
{
isNew: true
}
]
}
4.定义表格中的插槽
使用template定义插槽展示的内容
插槽中,slot对应表格列定义数据(tableColums)中的的slot,slot-scope中可以获取该行的数据,也就是tableData数组中每个元素对象。
使用if判断isNew来决定展示原数据还是输入框[难点1解决]
<Table
:columns="tableColums"
:data="formData.tableData"
>
<template slot="msgType" slot-scope="{ index, row }">
<span v-if="!row.name">{{ row.name }}</span>
<Form-item
v-else
:prop="'tableData.' + index + '.name'"
:rules="{required: true, message: '请输入报文类型', trigger: 'change'}"
>
<Input
v-model="formData.tableData[index].name"
:placeholder="$t('flightCGManageRule.placeholder')"
size="small"
style="width: 100%"
></Input>
</Form-item>
</template>
</Table
在form-item中使用rules来增加自定义校验方式,使用prop来决定校验的数据来源,这里iview的游戏规则是:如果form绑定的对象(formData)中包含数组时,要绑定数组中对象的字段,则需要Form-item中的prop命名为”数组字段名.数组下标.字段名“,如prop="tableData.0.name"则表示绑定的tableData中第一个元素中的name字段,rules中的校验的数据来源则来自该字段。
所以动态生成prop就可以动态绑定校验数据[难点3解决]
最后就是Input组件,该组件需要绑定表单数据,直接使用v-model="formData.tableData[index].name"即可动态绑定到数组中的每个数据[难点2解决]