1、序言
项目地址如下:https://gitee.com/liu-wenxin/complexELTable.git
想要渲染这样的数据:
el-table官网给的例子都是一级对象数组,如果想要渲染二级对象数组,直接
:table = tableData 这样el-table渲染是不成功的!我想过能否在<el-table></el-table>中直接使用<template slot-scope="scope"></template>去获取scope.row.memberList,然后在遍历scope.row.memberList生成<el-table-column></el-table-column>,然而这是不可行的,<template slot-scope="scope"></template> 必须在 <el-table-column></el-table-column>标签里面使用,如下2、3、4是我的实现方式以及一些思考!
2、表格嵌套(不推荐)
在<el-table-column></el-table-column>中嵌套<el-table></el-table> ,然后通过插槽row.memberList方式去赋值给data,效果如图所示:
优点:确实实现了渲染二级对象数组的效果
缺点:如果二级对象数组很长,我想对比不同行的不同模块的数据就会不直观,比如:我想要比较高一工科、高二工科数据就不方便,还要反复上下滚动,不直观!
<template>
<div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="grade" label="年级" width="180"></el-table-column>
<el-table-column>
<template slot-scope="{row}">
<el-table :data="row.memberList" border style="width: 100%">
<el-table-column prop="category" label="类型"></el-table-column>
<el-table-column prop="people" label="总人数"></el-table-column>
<el-table-column prop="boy" label="男"></el-table-column>
<el-table-column prop="girl" label="女"></el-table-column>
</el-table>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'Demo1',
data() {
return {
tableData: [
{
grade: '高一',
memberList: [
{ category: '文科', people: 300, boy: 40, girl: 260, },
{ category: '理科', people: 210, boy: 150, girl: 60 },
]
},
{
grade: '高二',
memberList: [
{ category: '文科', people: 100, boy: 40, girl: 60, },
{ category: '理科', people: 200, boy: 160, girl: 40 },
]
},
{
grade: '高三',
memberList: [
{ category: '文科', people: 150, boy: 50, girl: 100, },
{ category: '理科', people: 230, boy: 100, girl: 130 },
]
},
]
}
}
}
</script>
<style scoped></style>
3、树形控件结合表格(不推荐)
这种二级对象数组可以把下图的grade抽出来放在一个数组,将数组放在el-tree树形组件中,点击树形结构中的数据,将选中的数据在tableData中查询(也就是filter数组过滤),从而把memberList过滤出来,赋值到右侧的表格数组,从而实现类似索引查找功能!
代码如下:
<template>
<div>
<el-row :gutter="10">
<el-col :span="5" :md="5">
<!-- 树形结构 -->
<el-tree :data="leftData" highlight-current :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</el-col>
<el-col :span="19" :md="19">
<!-- 表格 -->
<el-table :data="rightData" border style="width: 100%">
<el-table-column prop="category" label="类型"></el-table-column>
<el-table-column prop="people" label="总人数"></el-table-column>
<el-table-column prop="boy" label="男"></el-table-column>
<el-table-column prop="girl" label="女"></el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [
{
grade: '高一',
memberList: [
{ category: '文科', people: 300, boy: 40, girl: 260, },
{ category: '理科', people: 210, boy: 150, girl: 60 },
]
},
{
grade: '高二',
memberList: [
{ category: '文科', people: 100, boy: 40, girl: 60, },
{ category: '理科', people: 200, boy: 160, girl: 40 },
]
},
{
grade: '高三',
memberList: [
{ category: '文科', people: 150, boy: 50, girl: 100, },
{ category: '理科', people: 230, boy: 100, girl: 130 },
]
},
],
rightData: [],
leftData: [],
defaultProps: {
label: 'grade'
}
}
},
created() {
this.generateLeftData();
},
methods: {
// 树形结构点击事件
handleNodeClick(data) {
this.searchData(data.grade);
},
// 根据tableData生成左边数据
generateLeftData() {
this.leftData = this.tableData.map(item => { return { grade: item.grade } })
},
// 点击左侧树形结构,查找tableData,并将搜索结果赋值到右侧表格
searchData(searchData) {
this.rightData = this.tableData.find(item => item.grade == searchData).memberList
}
}
}
</script>
<style scoped></style>
优点:实现了效果
缺点:不能对比、不直观!
4、多表头(推荐)
我们可以像官网那样使用多表头来渲染二级对象数组,不过官网的多表头是写死的,
是el-table-column的多层嵌套,数据还是一级对象数组
这种情况下,我们要分析一下数据结构,哪部分是固定不变的,哪部分是变化的
把固定的部分抽离出来:
// 二级表头名称映射
columnMap: {
people: '人数',
boy: '男',
girl: '女'
},
// 二级表头字段
columnList: ['people', 'boy', 'girl'],
// 一级表头
tyleList: ['文科', '理科'],
- 首先遍历typeList
- 其次遍历columnList
- 最后根据<template slot-scope="scope"></template>获取行数据,获取row.memberList
最终效果:这样就非常直观清晰了,对比度很明显,便于数据分析了!
代码如下:
<template>
<div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="grade" label="年级" width="180"></el-table-column>
<el-table-column v-for="(item, index) in tyleList" :label="item" align="center">
<el-table-column v-for="(i, j) in columnList" :label="columnMap[i]">
<template slot-scope="{row}">
{{ row.memberList[index][i] }}
</template>
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
columnMap: {
people: '人数',
boy: '男',
girl: '女'
},
columnList: ['people', 'boy', 'girl'],
tyleList: ['文科', '理科'],
tableData: [
{
grade: '高一',
memberList: [
{ category: '文科', people: 300, boy: 40, girl: 260, },
{ category: '理科', people: 210, boy: 150, girl: 60 },
]
},
{
grade: '高二',
memberList: [
{ category: '文科', people: 100, boy: 40, girl: 60, },
{ category: '理科', people: 200, boy: 160, girl: 40 },
]
},
{
grade: '高三',
memberList: [
{ category: '文科', people: 150, boy: 50, girl: 100, },
{ category: '理科', people: 230, boy: 100, girl: 130 },
]
},
]
}
}
}
</script>
<style lang="scss" scoped></style>