如题element-ui 2.13.2版本支持树形结构tabel,多层级折叠显示
但是没有多选 + 树形tabel, 业务需求的情况下必须要实现,操作勾选数据编辑
这里我们可以用两个事件来实现:
@select:用户勾选某行触发事件,第一个参数selection:所有选中的数据, 第二参数row:勾选的这行数据)
@select-all : 表头的全选、反选触发事件,只有一个参数selection:所有选中的数据
1、多选的处理函数(文档实例):
toggleSelection(rows) { if (rows) { rows.forEach(row => {
// toggleRowSelection有两个参数,第一个是每个选中数据,第二个是点击勾选的这行是否选中,树形结构需要,不然子集选中,本身不给选中 this.$refs.multipleTable.toggleRowSelection(row, true); }); } else { this.$refs.multipleTable.clearSelection(); } },
2、现在再来处理多选和单选,调用 toggleSelection 即可
因为树形结构的数据结构不符合选中数据格式,因此需要进行过滤处理
// 采用普通表格,然后进行样式和交互处理 <el-table :data="tableData" ref="multipleTable" :row-class-name="tabelStyle" // 处理折叠样式 或者使用 :row-style 注意函数返回的必须是Object @select="rowSelect" @select-all="selectAll" align="center" border> <el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="id" width="55">
<template slot-scope="scope">
<span @click="togglerShow(scope.row.id)> // 折叠图标和点击控制
<i v-if="scope.row.children && scope.row.children.length" class="el-icon-arrow-right"></i>
<i v-else class="el-icon-arrow-down"></i>
</span>
<span>{{scope.row.id}}</span>
</template>
</el-table-column>
...
</el-talbe>
// js
methods: {
tabelStyle({row, rowIndex}) {
const show = row.show ? true : false
return show ? 'tr-show' : 'tr-hide'
},
togglerShow(val) {
this.tableData.map(item => {
if (item.id=== val) {
item.country= item.country+ ' ' // 预发不重新渲染数据
if (item.children && item.children.length) {
item.expanded = !item.expanded
} else {
item.show = !item.show
}
}
})
}
}
// scss
<style lang="scss">
.tr-show {
animation:treeTableShow 1s;-webkit-animation:treeTableShow 1s;
}
.tr-hide {
display:none;
}
</style>
// 模拟数据源 data = { list: [ { "id": "11", "country": "Australia", "enable": "1",
"region_id": '11', "children": [ { "id": "151", "country": "Capital",
"region_id": '11', "enable": "1" }, { "id": "152", "country": "Territory",
"region_id": "11", "enable": "0", }, { "id": "153", "country": "Northern Territory",
"region_id": "11", "enable": "0" }, { "id": "154", "country": "Queensland",
"region_id": "11", "enable": "1" }, { "id": "155", "country": "South Australia",
"region_id": '11', "enable": "1" } ] }, { "id": "58", "country": "Austria",
"region_id": "12", "enable": "1" }, { "id": "331", "country": "Azores",
"region_id": "13", "enable": "0" } ], message: "success", status: 200 }
简单的template 结构和模拟的数据源差不多,如上所示,children 包裹分层级
3、过滤函数 filterSelect, 选中的多层级需要处理数据才能实现正确的交互,即将层级里面children的数据依次取出来,组成数组 tableData, 即渲染的数据源
data() { return { tableData: [], level: 1 } } // methods 中获取到的数据源要经过这层过滤处理 filterSelect(data) { data.forEach(item => { item.level = String(this.level) // 层级 item.show = this.level === 1 ? true : false // 判断是否折叠 item.isChecked = false; // 判断是否勾选重要参数 this.tableData.push(item) // 收集过滤后的数据,将children数据全部取出来 if (item.children && item.children.length > 0) { item.expanded = true // 顶层下有折叠 item.show = true // 顶层显示 this.level++ this.recursionArr(item.children) } }); }
4、实现符合逻辑的勾选交互
表头全选函数:
selectAll(selection) { // selection 是选中的数据集合
this.tableData.map(item => {
item.isChecked = !item.isChecked // 处理每条数据isChecked 选择状态
})
}
单行(多层级,目前只做了二级)全选、单选:
rowSelect(selection, row) { let changeArr = [] if (row.level === '1') { if (row.isChecked) { selection.map(item => { if (row.region_id !== item.region_id) { changeArr.push(item) } else { this.$refs.multipleTable.toggleRowSelection(item) } }) } else { this.tableData.map((item,index) => { if (row.region_id === item.region_id) { changeArr.push(item) } }) changeArr = changeArr.concat(selection) } } else if (row.level === '2') { changeArr = selection if (!row.isChecked) { this.tableData.map(item => { if (row.region_id === item.region_id && item.level === '1') { changeArr.push(item) } }) } } changeArr = [...new Set(changeArr)] // 去重 // 更新isChecked 状态 this.tableData.map(item => { if (item.id === row.id) { item.isChecked = !item.isChecked } }) // 正反选 if (changeArr.length) { this.toggleSelection(changeArr) } else { // 清除所有 this.$refs.multipleTable.clearSelection(); } }
以上就可以实现多选树形结构的操控
注: 如有需要参考的,请注意源数据模型和template结构中的参数配置,全选(多层级)、单选、过滤这三个函数,注意里面的数据源变量名this.tableData,目前多选、单选只做了两层级,有兴趣的同学可以补充完整