elment UI 表格 item 驗證問題解決方案

Hsumo發表於2018-07-05

需求背景

各位大拿,不知道你們在平時工作中有沒有遇到要在明細表格中又有各種操作以及規格驗證的需求,如下圖:

elment UI 表格 item 驗證問題解決方案

效果如下:

elment UI 表格 item 驗證問題解決方案

難點

因為表格是可新增行的,而每條資料對應的欄位在表格中是一樣的,然後在做表單驗證的時候資料的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)"> ...`
複製程式碼

結語

好了,目前算是已經解決這個需求了,不知道有沒有小夥伴有更好的方案,歡迎賜教。

相關文章