需求背景
各位大拿,不知道你们在平时工作中有没有遇到要在明细表格中又有各种操作以及规格验证的需求,如下图:
效果如下:
难点
因为表格是可添加行的,而每条数据对应的字段在表格中是一样的,然后在做表单验证的时候数据的key必须要唯一的,而且得是对象,这两个数据的数据格式是不同的,我是这样想的,只要解决了映射关系,问题就能解决了。所以想出了下面的方法
解决方案
项目采用 Vue + Element UI 开发: 我目前采用的方案是在 el-table 外加了一层 el-form,然后声明 tableForm 来绑定表单数据,包括做一些表单验证, 声明 tableData 表示表格数据,用来做合计以及数据初始化等渲染, template 代码如下:
<el-form :rules="rules" :model="tableForm" ref='tableForm' size="small">
<div class='btn-row'>
<el-button type='primary' size="mini" @click="addRow">添加一行</el-button>
<el-button size="mini" @click="deleteRow">删除</el-button>
</div>
<el-table :data="tableData" show-summary @selection-change="handleSelectionChange" ref="table" :summary-method="getSummaries">
<el-table-column
prop="startDate"
label="出发日期"
min-width="160px"
>
<template slot-scope="scope">
<el-form-item :prop='"startDate" + scope.row.id' :rules="rules.startDate" class="form-item__margin">
<el-date-picker
v-model="tableForm['startDate' + scope.row.id]"
@input="changeValue('startDate', scope.$index, scope.row.id)"
type="date"
value-format="yyyy-MM-dd"
placeholder="选择日期"
>
</el-date-picker>
</el-form-item>
</template>
</el-table-column>
</el-table>
</el-form>
因为表单是可以添加行以及删除行的,而且操作并不在每一行中,所以这里需要有个标识,然后数据里面并没有可用的 id, 所以这里我做了以下操作:
// 初始化
init () {
const id = +moment()
const data = {...this.initData}
for (let [key, value] of Object.entries(this.initData)) {
this.$set(this.tableForm, `${key}${id}`, value)
}
data.id = id
this.tableData.push(data)
}
初始化的操作ok了 主要是加上了 id 以及将初始化字段展开平铺到 tableForm 对象中去,添加行的方法其实和 init 一样,就是做一个添加标识符以及展开操作,删除操作有些不一样,但也很简单
// 删除选中行
deleteRow () {
const {checkedRow, tableData} = this
if (!checkedRow.length) {
this.$message({
message: `没有选中项`,
type: 'warning'
})
return
}
const ids = []
checkedRow.forEach(item => {
ids.push(item.id)
})
const newTable = tableData.filter(item => {
return !ids.includes(item.id)
})
this.tableData = newTable
for (let [key, value] of Object.entries(this.tableForm)) {
for (let id of ids) {
if (key.includes(id)) {
delete this.tableForm[key]
}
}
}
},
注意在模板里的写法,
`<el-form-item :prop='"startDate" + scope.row.id' :rules="rules.startDate"> ...`
以及
`<component v-model="tableForm['startDate' + scope.row.id]" @input="changeValue('startDate', scope.$index, scope.row.id)"> ...`
结语
好了,目前算是已经解决这个需求了,不知道有没有小伙伴有更好的方案,欢迎赐教。