關(guān)鍵字:element-ui今布, el-table 经备,大量數(shù)據(jù),樹狀表格部默,展開折疊侵蒙,卡頓,懶加載
遇到難題:
element-ui里面的樹狀表格傅蹂,當(dāng)層級(jí)和數(shù)據(jù)過多的時(shí)候會(huì)出現(xiàn)點(diǎn)擊展開和折疊的時(shí)候卡頓纷闺。數(shù)據(jù)量大概是 30 x 4 x 2 x 3 x 10 = 7200。
我以為是源碼里的邏輯不好份蝴,debug源碼犁功,但是沒有發(fā)現(xiàn)原因,后求助同事婚夫,得出是dom元素過多導(dǎo)致的浸卦。
一次性加載所有數(shù)據(jù)的時(shí)候,折疊的元素都已經(jīng)加載了案糙,只是樣式為dispaly:none限嫌;
在點(diǎn)擊展開的時(shí)候靴庆,改變display樣式,因?yàn)樵匚恢米兓剑?yè)面發(fā)生回流炉抒,且元素多,所以開銷大稚叹。
參考:https://blog.csdn.net/qq_34893429/article/details/61425120
所以采取懶加載的方式焰薄,將數(shù)據(jù) 一層層加上去“切洌可以在點(diǎn)擊展開的時(shí)候像后端請(qǐng)求塞茅,也可以從備份的全量數(shù)據(jù)里面找到對(duì)應(yīng)層級(jí)。
這種處理方式會(huì)在展開過多時(shí)慢慢變得卡頓僚稿,所以需要提供一個(gè)邏輯凡桥,使得用戶可以一鍵回到第一層蟀伸,且卸載所有子節(jié)點(diǎn)蚀同。
初始化表格代碼:
this.tableDataCopy = res.data || [] // 備份的全量數(shù)據(jù)
this.tableData = JSON.parse(JSON.stringify(res.data)).map(item => { // 展示數(shù)據(jù)
// hasChildren 表示需要展示一個(gè)箭頭圖標(biāo)
item.hasChildren = item.children && item.children.length > 0
// 只展示一層
// 如果有children數(shù)據(jù),會(huì)自動(dòng)加載啊掏,就不是懶加載了蠢络,也可以配置tree-props里面的children為其他字段
item.children = null
// 記住層級(jí)關(guān)系
item.idList = [item.id]
return item
})
懶加載代碼:
// 展開
load (tree, treeNode, resolve) {
// 層級(jí)關(guān)系備份
const idCopy = JSON.parse(JSON.stringify(tree.idList))
// 查找下一層數(shù)據(jù)
let resolveArr = this.tableDataCopy
let id
// eslint-disable-next-line
while (id = tree.idList.shift()) {
const tarItem = resolveArr.find(item => item.id === id)
tarItem.loadedChildren = true
resolveArr = tarItem.children
}
// 處理下一層數(shù)據(jù)的屬性
resolveArr = JSON.parse(JSON.stringify(resolveArr))
resolveArr.forEach(item => {
item.hasChildren = item.children && item.children.length > 0
item.children = null
// 此處需要深拷貝,以防各個(gè)item的idList混亂
item.idList = JSON.parse(JSON.stringify(idCopy))
item.idList.push(item.id)
})
// 標(biāo)識(shí)已經(jīng)加載子節(jié)點(diǎn)
tree.loadedChildren = true
// 渲染子節(jié)點(diǎn)
resolve(resolveArr)
}
使表格回到只有一層的狀態(tài)
unload () {
this.showTable = false
// eslint-disable-next-line
this.$nextTick(() => this.showTable = true)
this.tableData = JSON.parse(JSON.stringify(this.tableDataCopy)).map(item => {
// hasChildren 表示需要展示一個(gè)箭頭圖標(biāo)
item.hasChildren = item.children && item.children.length > 0
// 只展示一層
item.children = null
// 記住層級(jí)關(guān)系
item.idList = [item.id]
return item
})
},
模板代碼
<el-table
v-if="showTable"
:data="tableData"
row-key="id"
border
lazy
max-height="540"
:load="load"
ref="table"
>
<el-table-column prop="statisticTime" label="日期" min-width="220">
</el-table-column>
</el-table>