1、需求:
- 构造动态表头(根据后台返回的具体内容,对表头进行增或者减)
- 第一列内容相同进行合并
2、最终效果:
3、动态表头:
新建组件:
<template>
<el-table-column :label="coloumnHeader.label" :prop="coloumnHeader.label">
<template v-for="item in coloumnHeader.children">
<tableColumn
v-if="item.children && item.children.length"
:key="item.id"
:coloumn-header="item"
/>
<el-table-column
v-else
:key="item.name"
:label="item.label"
:prop="item.prop"
/>
</template>
</el-table-column>
</template>
<script>
export default {
name: 'TableColumn',
props: {
coloumnHeader: {
type: Object,
required: true
}
}
}
</script>
主界面引用:
表头数据我是在后端做好之后传到前端的,对应这个格式,可以实现增加或减少。
<template>
<div class="app-container">
<el-table :data="tableData" style="width: 100%" :span-method="objectSpanMethod" border show-summary>
<template v-for="item in tableConfig">
<table-column
v-if="item.children && item.children.length"
:key="item.id"
:coloumn-header="item"
/>
<el-table-column
v-else
:key="item.id + 1"
:label="item.label"
:prop="item.prop"
/>
</template>
</el-table>
</div>
</template>
<script>
// 引入api
import TableColumn from '@/views/finance/components/Table.vue'
export default {
// 定义页面数据
components: { Treeselect, DynamicTable, TableColumn },
data() {
return {
// 表数据
tableData: [],
// 表头数据
tableConfig: [
{
"id": 2,
"label": "停车场名称",
"prop": "parkName",
"children": null
},
{
"id": 85,
"label": "日期",
"prop": "date",
"children": null
},
{
"id": 0,
"label": "微信支付",
"prop": "0",
"children": [
{
"id": 12,
"label": "交易笔数",
"prop": "count0",
"children": null
},
{
"id": 89,
"label": "交易金额",
"prop": "money0",
"children": null
}
]
},
{
"id": 1,
"label": "支付宝支付",
"prop": "1",
"children": [
{
"id": 40,
"label": "交易笔数",
"prop": "count1",
"children": null
},
{
"id": 61,
"label": "交易金额",
"prop": "money1",
"children": null
}
]
}
],
}
}
}
</script>
4、合并内容相同列:
element ui 官网提供了合并的方法 :span-method="objectSpanMethod"
官方文档:
通过给table
传入span-method
方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row
、当前列column
、当前行号rowIndex
、**当前列号columnIndex
**四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan
(跨几行),第二个元素代表colspan
(跨几列)。也可以返回一个键名为rowspan
和colspan
的对象。
具体实现:
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
// this.tableData 修改
// [7, 0, 0, 0, 0, 0, 0]
const _row = (this.filterData(this.tableData).one)[rowIndex]
const _col = _row > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col
}
}
},
过滤数据:(判断第一列内容是否相同 返回数组 由objectSpanMethod
进行控制是否合并)
filterData(arr) {
const spanOneArr = []
let concatOne = 0
arr.forEach((item, index) => {
if (index === 0) {
spanOneArr.push(1)
} else {
if (item.parkName === arr[index - 1].parkName) { // 第一列需合并相同内容的判断条件
spanOneArr[concatOne] += 1 // 跨行数+1
spanOneArr.push(0) // 数组后边补0
} else {
spanOneArr.push(1)
concatOne = index
}
}
})
return {
one: spanOneArr
}
},
5、完整代码
<template>
<div class="app-container">
<el-table
:data="tableData"
style="width: 100%"
:span-method="objectSpanMethod"
border
show-summary
>
<template v-for="item in tableConfig">
<table-column
v-if="item.children && item.children.length"
:key="item.id"
:coloumn-header="item"
/>
<el-table-column
v-else
:key="item.id + 1"
:label="item.label"
:prop="item.prop"
/>
</template>
</el-table>
</div>
</template>
<script>
import TableColumn from '@/views/finance/components/Table.vue'
export default {
// 定义页面数据
components: { TableColumn },
data() {
return {
// 表数据
tableData: [],
// 表头数据
tableConfig: [],
}
},
// 勾子
created() {
this.initTable()
},
// 方法
methods: {
filterData(arr) {
const spanOneArr = []
let concatOne = 0
arr.forEach((item, index) => {
if (index === 0) {
spanOneArr.push(1)
} else {
if (item.parkName === arr[index - 1].parkName) { // 第一列需合并相同内容的判断条件
spanOneArr[concatOne] += 1 // 跨行数+1
spanOneArr.push(0) // 数组后边补0
} else {
spanOneArr.push(1)
concatOne = index
}
}
})
return {
one: spanOneArr
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
// this.tableData 修改
// [7, 0, 0, 0, 0, 0, 0]
const _row = (this.filterData(this.tableData).one)[rowIndex]
const _col = _row > 0 ? 1 : 0
return {
rowspan: _row,
colspan: _col
}
}
},
// 初始化表格数据
initTable() {
//向后端请求表头数据、表格数据
},
}
}
</script>