elment UI 表格 item 验证问题解决方案

需求背景

各位大拿,不知道大家在平时工做中有没有遇到要在明细表格中又有各类操做以及规格验证的需求,以下图:javascript

效果以下:java

难点

由于表格是可添加行的,而每条数据对应的字段在表格中是同样的,而后在作表单验证的时候数据的key必需要惟一的,并且得是对象,这两个数据的数据格式是不一样的,我是这样想的,只要解决了映射关系,问题就能解决了。因此想出了下面的方法bash

解决方案

项目采用 Vue + Element UI 开发: 我目前采用的方案是在 el-table 外加了一层 el-form,而后声明 tableForm 来绑定表单数据,包括作一些表单验证, 声明 tableData 表示表格数据,用来作合计以及数据初始化等渲染, template 代码以下:ui

<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, 因此这里我作了如下操做:this

// 初始化
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 同样,就是作一个添加标识符以及展开操做,删除操做有些不同,但也很简单spa

// 删除选中行
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]
      }
    }
  }
},
复制代码

注意在模板里的写法,code

`<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)"> ...`
复制代码

结语

好了,目前算是已经解决这个需求了,不知道有没有小伙伴有更好的方案,欢迎赐教。component

相关文章
相关标签/搜索