需求:表格每一列有一個按鈕字段,點擊后需要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)
})
}