el-table表格树状图复选框全选问题
应用场景
表格数据有层级关系,需要用到表格的树状图结构!!!,同时,可全选表格数据,跟全勾选子节点数据,效果如下
实现方法
根据element官网实现,实现完,发现树形表格加复选框后,子结构无法选中的问题。于是在table上监听点击和全选,根据数据有子节点来手动切换选中与否。
解决方法如下:
template如下:
<el-table ref="table" :data="tableData" style="width: 100%;margin-bottom: 20px;" row-key="id" border :indent="50" :select-on-indeterminate="false" @select="select" @select-all="selectAll" @selection-change="selectionChange" default-expand-all :tree-props="{children: 'childList'}"> <el-table-column type="selection" width="55"> </el-table-column> <el-table-column prop="date" label="日期" sortable width="180"> </el-table-column> <el-table-column prop="name" label="姓名" sortable width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> </el-table>
data格式如下
data () { return { checkedKeys: false, // 是否全部选中 isLoading: true, treeProps: { children: 'children', hasChildren: 'hasChildren' } // 树状图的配置项 } },
数据格式
tableData: [{ id: 1, date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { id: 2, date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { id: 3, date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄', childList: [{ id: 31, date: '2016-05-31', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, { id: 32, date: '2016-05-32', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }] }, { id: 4, date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }]
script代码如下
实现全选功能
setChildren (children, type) { // 编辑多个子层级 children.map(j => { this.toggleSelection(j, type) if (j.childList) { this.setChildren(j.childList, type) } }) }, // 选中父节点时,子节点一起选中取消 select (selection, row) { if (selection.some(el => { return row.id === el.id })) { if (row.childList) { // row.childList.map(j => { // this.toggleSelection(j, true) // }) // 解决子组件没有被勾选到 this.setChildren(row.childList, true) } } else { if (row.childList) { // row.childList.map(j => { // this.toggleSelection(j, false) // }) this.setChildren(row.childList, false) } } }, toggleSelection (row, select) { if (row) { this.$nextTick(() => { this.$refs.table && this.$refs.table.toggleRowSelection(row, select) }) } }, // 选择全部 selectAll (selection) { // tabledata第一层只要有在selection里面就是全选 const isSelect = selection.some(el => { const tableDataIds = this.tableData.map(j => j.id) return tableDataIds.includes(el.id) }) // tableDate第一层只要有不在selection里面就是全不选 const isCancel = !this.tableData.every(el => { const selectIds = selection.map(j => j.id) return selectIds.includes(el.id) }) console.log(isSelect, 'isSelect') if (isSelect) { selection.map(el => { if (el.childList) { // el.childList.map(j => { // this.toggleSelection(j, true) // }) // 解决子组件没有被勾选到 this.setChildren(el.childList, true) } }) } if (isCancel) { this.tableData.map(el => { if (el.childList) { // el.childList.map(j => { // this.toggleSelection(j, false) // }) // 解决子组件没有被勾选到 this.setChildren(el.childList, false) } }) } this.$emit('handleSelect', this.tableData) }
select函数是表示选中父节点,子节点跟着选中,selectAll是选中全部
经过上面的方法。我们的复选框,子节点不被选中问题已经解决,到时候这个时候会发现,我们在触发全部选中的方法select-all时,会同时触发selection-change方法,这时候穿给后端的是整个表格的数据,但是我们只需要传给后端父节点,我们可以通过下面的方法来进行过滤
let tableAllId = this.tableData.map(item => item.nodeKey) // 所有父节点的id let selectIds = rows.map(item => item.nodeKey) // 所有选中的节点id集合 let isAllSelect = tableAllId.every(item => selectIds.includes(item)) if (isAllSelect) { // 全选表格数据 this.currentSelectedRows = tableAllId } else { this.currentSelectedRows = selectIds }