我们在使用table组件时,一般获取勾选的值时有@selection-change回调可以获取到,但是,这只适用于表格数据没有子数据,如果表格有子数据,可以这样获取,肯定的是不能使用@selection-change获取了
html
<template>
<div>
<el-table
:ref="tableRef"
border
:data="tableData"
:row-class-name="tableRowClassName"
row-key="id"
:span-method="objectSpanMethod"
style="width: 100%"
@cell-mouse-enter="handleCellMouseEnter"
@cell-mouse-leave="handleCellMouseLeave"
@select="handleSelect"
@select-all="handleSelectAll"
>
<el-table-column align="center" type="selection" width="55" />
<el-table-column align="center" label="部门" prop="deptName" width="180" />
<el-table-column align="center" label="姓名" prop="name" width="180" />
<el-table-column align="center" label="职位" prop="position" />
<el-table-column align="center" class-name="small-padding fixed-width" fixed="right" label="操作" width="140">
<template slot-scope="_scope">
<el-button size="mini" type="text">修改</el-button>
<el-button size="mini" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'Index',
data() {
return {
tableData: [],
tableRef: 'table',
optionKey: {
parentIdKey: 'parentId',
childIdKey: 'id',
subKey: 'users',
},
groupData: [
{
parentId: 1,
deptName: '技术部',
users: [
{ id: 11, name: '张三', position: '高级前端工程师' },
{ id: 12, name: '李四', position: '前端工程师' },
{ id: 13, name: '王五', position: 'UI设计师' },
],
},
{
parentId: 2,
deptName: '市场部',
users: [
{ id: 21, name: '赵六', position: '营销经理' },
{ id: 22, name: '钱七', position: 'SEO专员' },
],
},
{
parentId: 3,
deptName: '人事部',
users: [
{ id: 31, name: '王八', position: '招聘经理' },
{ id: 32, name: '吴九', position: '招聘专员' },
],
},
{
parentId: 4,
deptName: '外交',
users: [
{ id: 41, name: '王琨', position: '外交一' },
{ id: 42, name: '吴飞', position: '外交二' },
],
},
],
currentParentId: '',
}
},
created() {
this.getList()
},
methods: {
addStripedData(groupData, key) {
return groupData.map((group, index) => {
// 如果 group[key] 不存在或长度为0,直接给 group 添加 striped
if (!group[key] || group[key].length === 0) {
return {
...group,
striped: index % 2 !== 0,
}
}
// 如果 group[key] 有数据,给每个子项添加 striped
return {
...group,
[key]: group[key].map((child) => ({
...child,
striped: index % 2 !== 0,
})),
}
})
},
/** 查询公告列表 */
getList() {
const groupData = this.addStripedData(this.groupData, this.optionKey.subKey)
this.tableData = groupData.flatMap((row) => {
// : children 表示将取出的值赋给变量 children
const { [this.optionKey.subKey]: children, ...outerFields } = row
if (!children || children.length === 0) {
return [{ ...outerFields }]
}
return children.map((item) => ({
...item,
...outerFields,
}))
})
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 只在部门列合并
if (column.property === 'deptName' || column.type === 'selection') {
// 找到当前行所属的分组
const group = this.groupData.find((g) => {
return g[this.optionKey.subKey].some((child) => child[this.optionKey.childIdKey] === row[this.optionKey.childIdKey])
})
if (!group) {
return {
rowspan: 1,
colspan: 1,
}
}
// 如果是分组的第一行,返回合并行数
if (group[this.optionKey.subKey][0][this.optionKey.childIdKey] === row[this.optionKey.childIdKey]) {
return {
rowspan: group[this.optionKey.subKey].length,
colspan: 1,
}
} else {
// 其他行不显示
return {
rowspan: 0,
colspan: 0,
}
}
}
},
// 处理单选
handleSelect(selection, row) {
const isSelected = selection.some((item) => item[this.optionKey.childIdKey] === row[this.optionKey.childIdKey])
const groupItems = this.tableData.filter((item) => item[this.optionKey.parentIdKey] === row[this.optionKey.parentIdKey])
if (isSelected) {
// 选中:添加同组所有项
groupItems.forEach((item) => {
if (!selection.some((selected) => selected[this.optionKey.childIdKey] === item[this.optionKey.childIdKey])) {
this.$refs.table.toggleRowSelection(item, true)
}
})
} else {
// 取消选中:移除同组所有项
groupItems.forEach((item) => {
this.$refs.table.toggleRowSelection(item, false)
})
}
this.handleSelectedRows(this.$refs[this.tableRef].selection)
},
// 处理全选
handleSelectAll(selection) {
this.handleSelectedRows(selection)
},
handleSelectedRows(selection) {
const parentIdSet = new Set(selection.map((item) => item[this.optionKey.parentIdKey]))
//这里就是勾选后获取的正确值
const result = this.groupData.filter((item) => parentIdSet.has(item[this.optionKey.parentIdKey]))
},
// this.$baseLodash
tableRowClassName({ row, column, rowIndex, columnIndex }) {
//逻辑判断决定是否修改样式,如果分组一致则使用同一个样式
const classNames = []
// 斑马纹样式
if (row.striped) {
classNames.push('striped-bg')
}
// 高亮当前父级相关的行
if (row[this.optionKey.parentIdKey] === this.currentParentId) {
classNames.push('hover-bg')
}
return classNames.join(' ')
},
// 鼠标移入
handleCellMouseEnter(row, column, rowIndex, columnIndex) {
//标记当前是哪个分组
this.currentParentId = row[this.optionKey.parentIdKey]
},
// 鼠标移出
handleCellMouseLeave() {
//移出是清空光标
this.currentParentId = ''
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .el-table {
.el-table__body .el-table__row {
&.hover-bg td {
background-color: #f5f7fa !important;
}
&.striped-bg td {
background-color: #ebebeb;
}
}
}
</style>