须知
这是 vue2
版本,不过理论上 vue3
也能参考使用
可以直接打开 codepen 查看代码
效果图
代码
打不开 codepen
或者codepen
失效,查看下面代码参考
<script src="//unpkg.com/vue@2/dist/vue.js"></script>
<script src="//unpkg.com/element-ui@2.15.14/lib/index.js"></script>
<div id="app">
<template>
<div>
<el-button @click="logMergedRowCount">Log</el-button>
<el-table row-key="id" @expand-change="expandChange" :data="tableData" :span-method="objectSpanMethod" border :tree-props="{children: 'children', hasChildren: 'hasChildren'}" style="width: 100%; margin-top: 20px">
<el-table-column prop="name" label="姓名">
</el-table-column>
<el-table-column prop="id" label="ID" width="180">
</el-table-column>
<el-table-column prop="amount1" label="数值 1(元)">
</el-table-column>
<el-table-column prop="amount2" label="数值 2(元)">
</el-table-column>
<el-table-column prop="amount3" label="数值 3(元)">
</el-table-column>
</el-table>
</div>
</template>
</div>
@import url("//unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css");
var Main = {
data() {
return {
tableData: [],
spanMap: {}, // 每层的 id => {子级有几个, 祖宗是谁}
expandRowKeys: {}
};
},
computed: {
parentMap() {
const keys = Object.entries(this.expandRowKeys)
.filter(([k, v]) => v)
.map(([k]) => k);
console.log("keys", keys);
let result = {};
for (const item of keys) {
const expandRow = this.spanMap[item];
if (result[expandRow.parentId]) {
result[expandRow.parentId] += expandRow.childCount;
} else {
result[expandRow.parentId] = expandRow.childCount;
}
}
return result;
}
},
mounted() {
let datalist = [
{
id: "1",
name: "一级事件",
amount1: "165",
amount2: "4.43",
amount3: 12,
children: [
{
id: "2",
name: "二级事件1",
amount1: "165",
amount2: "4.43",
amount3: 12,
children: [
{
id: "3",
name: "三级事件1",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "4",
name: "三级事件2",
amount1: "165",
amount2: "4.43",
amount3: 12
}
]
},
{
id: "5",
name: "二级事件2",
amount1: "165",
amount2: "4.43",
amount3: 12
}
]
},
{
id: "6",
name: "一级事件2",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "7",
name: "二级事件1",
amount1: "165",
amount2: "4.43",
amount3: 12,
children: [
{
id: "8",
name: "三级事件1",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "9",
name: "三级事件2",
amount1: "165",
amount2: "4.43",
amount3: 12
}
]
},
{
id: "10",
name: "三级事件1",
amount1: "165",
amount2: "4.43",
amount3: 12
},
{
id: "11",
name: "三级事件2",
amount1: "165",
amount2: "4.43",
amount3: 12
}
];
datalist = this.preprocessData(datalist);
this.tableData = datalist;
},
methods: {
/**
* 处理行展开状态变化的事件。
* @param {Object} row - 当前行的数据对象。
* @param {boolean} expanded - 表示行是否被展开。
*/
expandChange(row, expanded) {
// 使用 Vue 的 $set 方法更新展开行的键值对,确保响应性
this.$set(this.expandRowKeys, row.id, expanded);
},
/**
* 打印合并行数的日志。
*/
logMergedRowCount() {
// 打印合并行数的映射,用于调试或检查合并状态
console.log(this.mergedRowCount);
},
preprocessData(data, id = "") {
return data.map((item) => {
const newItem = { ...item };
newItem.parentId = id; // 将当前路径作为 parentId 属性
if (this.spanMap[item.id]) {
this.spanMap[item.id].childCount = item.children?.length || 0;
} else {
this.spanMap[item.id] = {
childCount: item.children?.length || 0,
parentId: id || item.id
};
}
if (item.children && item.children.length > 0) {
newItem.children = this.preprocessData(item.children, id || item.id);
}
return newItem;
});
},
//进行表格合并
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
if (row.parentId) {
return {
rowspan: 0,
colspan: 0
};
} else {
console.log("row.id", this.parentMap[row.id]);
return {
rowspan: (this.parentMap[row.id] ?? 0) + 1,
colspan: 1
};
}
}
}
}
};
var Ctor = Vue.extend(Main);
new Ctor().$mount("#app");