1. 程式人生 > 實用技巧 >elementui 表格中帶有按鈕的loading解決方案

elementui 表格中帶有按鈕的loading解決方案

需求:表格每一列有一個按鈕欄位,點選後需要loading

按照普通的在 Array 物件上加屬性,監聽不到變化,需要使用 this.$set

比如這個樣子設定

getCoreLoots().then(response => {
  this.transitFileList = response.data.data
  this.transitFileList = this.transitFileList.map(item => {
    // 新增上傳按鈕loading
    item.uploadLoading = false
    return item
  })
  console.log(this.transitFileList)
  this.transitListLoading = false
})

這樣子出來的結果是這樣

屬性設定到了 ob 外面,vue監聽不到變化,也就是說我們進行改變後dom不會更新

主要的原因是:當你把一個普通的 JavaScript 物件傳入 Vue 例項作為 data 選項,Vue 將遍歷此物件所有的 property,並使用 Object.defineProperty 把這些 property 全部轉為 getter/setter。這些 getter/setter 對使用者來說是不可見的,但是在內部它們讓 Vue 能夠追蹤依賴,在 property 被訪問和修改時通知變更。Vue 無法檢測 property 的新增或移除。由於 Vue 會在初始化例項時對 property 執行 getter/setter 轉化,所以 property 必須在 data 物件上存在才能讓 Vue 將它轉換為響應式的。

知道了原因之後我們可以做一下略微的改造

getCoreLoots().then(response => {
  this.transitFileList = response.data.data
  this.transitFileList = response.data.data.map(item => {
    // 新增上傳按鈕loading
    item.uploadLoading = false
    return item
  })
  console.log(this.transitFileList)
  this.transitListLoading = false
})

現在可以看到在 ob 裡面了。

同樣,如果你有更多的需求可以按照官方文件中的使用 set 來進行設定

例如

<el-table-columnlabel="操作" width="145">
  <template slot-scope="scope">
    <el-button type="text" :loading="scope.row.uploadLoading" size="mini" @click="handleClickUploadTransitFileToTarget(scope)">上傳到目標</el-button>
  </template>
</el-table-column>

...

getTransitFileList() {
  getCoreLoots().then(response => {
    this.transitFileList = response.data.data
    this.transitFileList = this.transitFileList.map(item => {
      // 新增上傳按鈕loading
      this.$set(item, 'uploadLoading', false)
      return item
    })
  })
},


handleClickUploadTransitFileToTarget(scope) {
  this.$set(scope.row, 'uploadLoading', true)
  uploadFileToTarget().then(response => {
    showMsg(this, `${scope.row.name} 上傳成功`)
    this.$set(scope.row, 'uploadLoading', false)
  })
}