element el-table实现树形可选择表格
之前写了一篇用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) } } }