之前寫了一篇用el-tree實現可選擇樹形表格的博客
最近再次有這種樹形表格的需求,研究了下,發現用el-table本身支持的樹形數據改造下也可以實現
兩種方式都可以實現需求,這里只是多提供一種思路,至於選擇哪一種方法,根據實際情況
用el-tree實現
優點: 1.不用處理數據層級關系, 2.選擇時的互動效果比較好 3.多層級數據也適用
缺點: 1. 需要自己寫表頭樣式, 額外的表格樣式較多, 2.不能用表格的一些便利屬性(排序, 篩選...)
用el-table實現
優點: 1.樣式可以使用自帶的,不用自定義表頭,表格樣式 2.可以無負擔的使用表格的屬性
缺點: 1.需要自己處理點擊時父子聯動效果 2.層級較多時處理數據將變得很復雜
完成效果:

實現:
<el-table
:data="tableData2"
style="width: 100%;margin-bottom: 20px;"
row-key="id"
border
default-expand-all
<!-- 子級縮進距離 -->
:indent="indent"
<!-- 如果返回的數據,子級不是children,需要在這里指定 -->
:tree-props="{children: 'childs'}">
<el-table-column
width="75">
<!-- 表格頭的選擇框 -->
<template slot="header" slot-scope="scope">
<el-checkbox v-model="checkedAll" @change="changeAllSelect" />
</template>
<!-- 表格行的選擇框, 如果是父級,設置一個indeterminate顯示未全選的樣式 -->
<template slot-scope="scope">
<el-checkbox
v-if="scope.row.childs"
:indeterminate="scope.row.indeterminate"
v-model="scope.row.checked"
@change="changeRowSelect(scope.row)"
/>
<el-checkbox
v-else
v-model="scope.row.checked"
@change="changeRowSelect(scope.row)"
/>
</template>
</el-table-column>
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
<el-table-column label="操作" width="80">
<template slot-scope="scope">
<el-button
size="mini"
>詳情</el-button>
</template>
</el-table-column>
</el-table>
checkbox需要自己寫,不能使用el-table的type="selection",伸縮圖標位置不對
有一個樣式要注意一下, 可以使用indent設置子級縮進距離,使層級看起來更明顯,默認是16px

js:
export default { template, data () { return { tableData2: [], checkedAll: false, // 是否全選 } }, created() { this.getTree() }, // 方法集合 methods: { // 獲取表格數據 async getTree () { const { data } = await getTreeData() console.log(data) this.tableData2 = data }, // 選擇表格(全選) changeAllSelect (val) { // console.log(val) const loop = (data) => { data.forEach(item => { item.checked = val if ('indeterminate' in item) { item.indeterminate = false } if (item.childs) { loop(item.childs) } }) } loop(this.tableData2) }, // 選擇表格(表格行選擇) changeRowSelect (val) { // console.log(val) if (!isEmpty(val.childs)) { val.childs.forEach(ss => { ss.checked = val.checked }) } else { let checkedLeg = 0 this.tableData2.some(item => { if (item.id === val.parentId) { // 獲取當前父級下子級選中條數 const leg = item.childs.length checkedLeg = item.childs.filter(ss => ss.checked).length // 根據條數改變父級的indeterminate和checked if (checkedLeg === 0) { item.indeterminate = false item.checked = false } else if (checkedLeg < leg) { item.indeterminate = true item.checked = false } else if (checkedLeg === leg) { item.indeterminate = false item.checked = true } return } }) // console.log(this.tableData2) } // 判斷是否全部選擇了,改變全選框的樣式 let flag = true this.tableData2.some(item => { if (!item.checked) { flag = false return } }) this.checkedAll = flag }, // 點擊提交選中的表格 handleSelectTable () { const selectedIds = [] const loop = (data) => { data.forEach(item => { if (item.checked || item.indeterminate) { selectedIds.push(item.id) if (item.childs) { loop(item.childs) } } }) } loop(this.tableData2) console.log(selectedIds) } } }