Element表格資料沒有重新渲染

老毛發表於2021-10-28

具體需求說明

有這樣一個表格
table
點選編輯後
edit
可以直接修改姓名,確定儲存,或者取消恢復到之前的狀態,線上的演示地址我放到下邊,如果你願意的話可以自己去把玩一下。
Demo

在國內訪問Demo的速度會很慢,或者就是無法訪問,原因你懂的O(∩_∩)。也許你需要一個穩定的梯子?,可以檢視這篇文章Link

上程式碼

<template>
  <div class="demo-block">
    <el-table
        border
        size="mini"
        :data="tableData"
        style="width: 400px">
      <el-table-column
          label="姓名"
          width="180">
        <template slot-scope="scope">
          <el-input v-if="scope.row.editMode" v-model="input" size="mini" placeholder="請輸入內容"></el-input>
          <span v-else>{{ scope.row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button
              size="mini"
              @click="handleEdit(scope.$index, scope.row)">編輯</el-button>
          <el-button
              v-if="scope.row.editMode"
              size="mini"
              @click="handleCancel(scope.$index, scope.row)">取消</el-button>
          <el-button
              v-if="scope.row.editMode"
              size="mini"
              type="primary"
              @click="handleConfirm(scope.$index, scope.row)">確定</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: "Element",
  data() {
    return {
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1517 弄'
      }, {
        date: '2016-05-01',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1519 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀區金沙江路 1516 弄'
      }],
      input: ''
    }
  },
  methods: {
    handleEdit(index, row) {
      this.tableData = this.tableData.map((item, i) => {
        if (index === i) {
          item.editMode = true
        }
        return item
      })
      this.input = row.name;
    },
    handleCancel(index) {
      this.tableData = this.tableData.map((item, i) => {
        if (index === i) {
          item.editMode = false
        }
        return item
      })
    },
    handleConfirm(index) {
      this.tableData = this.tableData.map((item, i) => {
        if (index === i) {
          item.editMode = false
          item.name = this.input
        }
        return item
      })
    }
  }
}
</script>

<style scoped>
.demo-block {
  border: 1px solid #ebebeb;
  border-radius: 3px;
  transition: .2s;
}
</style>

思路就是在點選某一行的編輯按鈕時,給這一行的資料新增一個編輯的狀態。看下這個處理編輯事件的方法:

handleEdit(index, row) {
      this.tableData = this.tableData.map((item, i) => {
        if (index === i) {
          item.editMode = true
        }
        return item
      })
      this.input = row.name;
}

比較關鍵的點就是重新生成了一份tableData資料。這樣才能使表格重新渲染,再開始我曾嘗試使用:

handleEdit(index, row) {
      this.tableData.forEach((item, i) => {
        if (index === i) {
          item.editMode = true
        }
        return item
      })
      this.input = row.name;
}

這樣點選編輯後不會有任何反應的。

擴充套件總結

到這裡我們已經可以解決這個需求。但是我等並非等閒之輩就這麼容易滿足?,藉此機會研究一下JavaScript中一些可以生成新資料的方法:

  • 當然我們可以使用for迴圈,或者forEach來生成新的結構,但是遠不如map()優雅
  • 當我們需要篩選一個集合中的某些符合條件的子集filter方法會很方便,還用上邊的tableData舉例

    const list = tableData.filter((item, i) => {
    return i > 1
    })
    // 結果
    [{
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀區金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀區金沙江路 1516 弄'
    }]

    這樣得到的list就是除去前兩條資料的新集合,而原來的tableData並不會發生變化。

  • splice方法

    const removed = tableData.splice(0,1)
    
    // removed
    [{
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀區金沙江路 1519 弄'
    }]
    // 原集合會發生變化只剩下後三條資料
  • concat方法

    const arr = [{
          date: '2016-05-10',
          name: '王小虎',
          address: '上海市普陀區金沙江路 1519 弄'
    }]
    tableData.concat(arr)
    // 原集合會連結arr生成新的結構
    [{date: '2016-05-04', name: '王小虎', address: '上海市普陀區金沙江路 1517 弄'},
    {date: '2016-05-01', name: '王小虎', address: '上海市普陀區金沙江路 1519 弄'},
    {date: '2016-05-03', name: '王小虎', address: '上海市普陀區金沙江路 1516 弄'},
    {date: '2016-05-10', name: '王小虎', address: '上海市普陀區金沙江路 1519 弄'}]
  • 展開操作符(Spread)

    const arr = [...tableData]
    // arr 從 tableData複製了一份,原來的tableData不會變化
    先總結這麼多,後續可能還會補充...謝謝觀看?

相關文章