效果:
代码:
index.vue
<template><div class="my-table"><el-tablev-loading="table.loading":data="table.data"bordersize="mini":header-cell-style="headerCellStyle":span-method="spanMethod"><!-- 使用递归组件渲染表头 --><myColumnv-for="(item, index) in table.header":key="index":header="item"/></el-table></div>
</template><script>
// 引入组件
import myColumn from "./my-column.vue";export default {name: "Test1",components: { myColumn },data() {return {table: {loading: false,header: [],data: [],},};},computed: {},created() {},mounted() {// 表头this.table.header = [{prop: "date",label: "月份",width: "100px",children: [],fixed: false,},{prop: "project1",label: "",width: "100px",children: [],},{prop: "project2",label: "项目",width: "100px",position: "111",children: [],},{prop: "index",label: "序号",width: "50px",children: [],},{prop: "deliveryInfo",label: "线下合计",width: "560px",children: [{prop: "name",label: "2024",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "2023",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "增长",width: "80px",children: [{prop: "name1",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},],},{prop: "deliveryInfo",label: "东北",width: "560px",children: [{prop: "name",label: "2024",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "2023",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "增长",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},],},];// 数据this.table.data = [{date: "2016-05-03",project1: "数量",project2: "鞋",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",index: 0,name1: 10086,},{date: "2016-05-02",project1: "数量",project2: "包服配",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",index: 1,},{date: "2016-05-04",name: "王小虎",project1: "收入",project2: "实数收入",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-01",name: "王小虎",project1: "收入",project2: "无税收入",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-08",name: "王小虎",project1: "收入",project2: "有税收入",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-06",name: "王小虎",project1: "附加税金",project2: "附加税金",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-07",name: "王小虎",project1: "附加税金1",project2: "附加税金2",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},];},methods: {spanMethod({ row, column, rowIndex, columnIndex }) {// const rowData = Object.values(row);// if ((rowData[1] === rowData[2])) { // 根据实际需求变更if ((row['project1'] === row['project2'])) { // 根据实际需求变更// 跨列数据相同合并if (columnIndex === 1) {return [1, 2];} else if (columnIndex === 2) {return [0, 0]}} else {if (columnIndex === 1) {// 列数据相同合并const currentValue = row[column.property];const preRow = this.table.data[rowIndex - 1];const preValue = preRow ? preRow[column.property] : null;if (currentValue === preValue) {return [0, 0]} else {let rowspan = 1;for (let i = rowIndex + 1; i < this.table.data.length; i++) {const nextRow = this.table.data[i]const nextValue = nextRow[column.property]if (nextValue === currentValue) {rowspan++;} else {break;}}return [rowspan, 1];}}}},headerCellStyle({ row, column, rowIndex, columnIndex }) {let base = { "background": "#4389f94d",color: "#333" };if (column.label === "") {// 隐藏return { display: "none" };}if (column.property === "project2") { // 根据实际需求变更this.$nextTick(() => {if (document.getElementsByClassName(column.id).length !== 0) {document.getElementsByClassName(column.id)[0].setAttribute("colSpan", 2); // 根据实际需求变更}});}return base;},},
};
</script><style lang="scss" scoped></style>
my-column.vue
<template><el-table-column:prop="header.prop":label="header.label":fixed="header.fixed":min-width="header.width"align="center"show-overflow-tooltip><template v-if="header.children && header.children.length"><myColumn v-for="(child, index) in header.children" :key="index" :header="child" /></template></el-table-column>
</template><script>
export default {name: "myColumn",components: {},props: {header: {type: Object,required: true,},},data() {return {};},mounted() {},methods: {},
};
</script><style lang="scss" scoped></style>
附加:index.html模版
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>demo</title><!-- 引入样式 --><linkrel="stylesheet"href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"/><!-- 引入组件库 --><script src="https://unpkg.com/vue@2/dist/vue.js"></script><script src="https://unpkg.com/element-ui/lib/index.js"></script></head><body><div id="app"><div class="my-table"><el-tablev-loading="table.loading":data="table.data"bordersize="mini":header-cell-style="headerCellStyle":span-method="spanMethod"><!-- 使用递归组件渲染表头 --><mycolumnv-for="(item, index) in table.header":key="index":header="item"/></el-table></div></div><script type="text/javascript">//定义组件Vue.component("mycolumn", {props: {header: {type: Object,required: true,},},template: `<el-table-column :prop="header.prop" :label="header.label" :fixed="header.fixed" :min-width="header.width" align="center" show-overflow-tooltip><template v-if="header.children && header.children.length"><mycolumn v-for="(child, index) in header.children" :key="index" :header="child" /></template></el-table-column>`,});var vm = new Vue({el: "#app",data() {return {table: {loading: false,header: [],data: [],},};},mounted() {// 表头this.table.header = [{prop: "date",label: "月份",width: "100px",children: [],fixed: false,},{prop: "project1",label: "",width: "100px",children: [],},{prop: "project2",label: "项目",width: "100px",position: "111",children: [],},{prop: "index",label: "序号",width: "50px",children: [],},{prop: "deliveryInfo",label: "线下合计",width: "560px",children: [{prop: "name",label: "2024",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "2023",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "增长",width: "80px",children: [{prop: "name1",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},],},{prop: "deliveryInfo",label: "东北",width: "560px",children: [{prop: "name",label: "2024",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "2023",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},{prop: "name",label: "增长",width: "80px",children: [{prop: "name",label: "金额",width: "80px",},{prop: "name",label: "%",width: "80px",children: [],},],},],},];// 数据this.table.data = [{date: "2016-05-03",project1: "数量",project2: "鞋",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",index: 0,name1: 10086,},{date: "2016-05-02",project1: "数量",project2: "包服配",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",index: 1,},{date: "2016-05-04",name: "王小虎",project1: "数量",project2: "实数收入",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-01",name: "王小虎",project1: "收入",project2: "无税收入",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-08",name: "王小虎",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-06",name: "王小虎",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},{date: "2016-05-07",name: "王小虎",province: "上海",city: "普陀区",address: "上海市普陀区金沙江路 1518 弄",zip: 200333,},];},methods: {spanMethod({ row, column, rowIndex, columnIndex }) {// const rowData = Object.values(row);// if ((rowData[1] === rowData[2])) { // 根据实际需求变更if (row["project1"] === row["project2"]) {// 根据实际需求变更// 跨列数据相同合并if (columnIndex === 1) {return [1, 2];} else if (columnIndex === 2) {return [0, 0];}} else {if (columnIndex === 1) {// 列数据相同合并const currentValue = row[column.property];const preRow = this.table.data[rowIndex - 1];const preValue = preRow ? preRow[column.property] : null;if (currentValue === preValue) {return [0, 0];} else {let rowspan = 1;for (let i = rowIndex + 1; i < this.table.data.length; i++) {const nextRow = this.table.data[i];const nextValue = nextRow[column.property];if (nextValue === currentValue) {rowspan++;} else {break;}}return [rowspan, 1];}}}},headerCellStyle({ row, column, rowIndex, columnIndex }) {let base = { background: "#4389f94d", color: "#333" };if (column.label === "") {// 隐藏return { display: "none" };}if (column.property === "project2") {// 根据实际需求变更this.$nextTick(() => {if (document.getElementsByClassName(column.id).length !== 0) {document.getElementsByClassName(column.id)[0].setAttribute("colSpan", 2); // 根据实际需求变更}});}return base;},},});</script></body>
</html>