前一阵公司内有个需求,需要将后端返回的对象数据渲染在el-table中,将对象中所有的属性名作为列名动态渲染。并且每一列中都要对应相应的项目编码进行渲染。
完成后的样子为
数据大概是这个样子
Mock: {
"2021A": [
{ id: 1, val: "测试1" },
{ id: 3, val: "测试2" },
{ id: 5, val: "测试3" },
{ id: 11, val: "测试4" },
{ id: 2, val: "测试1" },
{ id: 10, val: "测试2" },
{ id: 4, val: "测试3" },
{ id: 6, val: "测试4" },
],
"2021B": [
{ id: 2, val: "测试5" },
{ id: 11, val: "测试6" },
{ id: 5, val: "测试7" },
{ id: 12, val: "测试8" },
],
"2021C": [
{ id: 1, val: "测试9" },
{ id: 6, val: "测试10" },
{ id: 7, val: "测试11" },
{ id: 17, val: "测试12" },
],
"2021D": [
{ id: 13, val: "测试13" },
{ id: 4, val: "测试14" },
{ id: 8, val: "测试15" },
{ id: 9, val: "测试16" },
],
"2021E": [
{ id: 13, val: "测试13" },
{ id: 4, val: "测试14" },
{ id: 8, val: "测试15" },
{ id: 9, val: "测试16" },
],
"2021F": [
{ id: 1, val: "测试13" },
{ id: 6, val: "测试14" },
{ id: 12, val: "测试15" },
{ id: 18, val: "测试16" },
{ id: 24, val: "测试16" },
],
},
可能在各位大佬眼中这个需求很简单,但是对于刚入行的我来说一切都需要学习,哈哈哈,在这里记录一下解决方案。
下面是完整的vue.js代码
<template>
<el-table :data="ArrList" stripe style="width: 100%" border>
<el-table-column prop="item_id" label="项目编码" width="180">
</el-table-column>
<el-table-column
:prop="item"
:label="item"
width="180"
v-for="item in tableHerd"
:key="item"
>
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
Mock: {
"2021A": [
{ id: 1, val: "测试1" },
{ id: 3, val: "测试2" },
{ id: 5, val: "测试3" },
{ id: 11, val: "测试4" },
{ id: 2, val: "测试1" },
{ id: 10, val: "测试2" },
{ id: 4, val: "测试3" },
{ id: 6, val: "测试4" },
],
"2021B": [
{ id: 2, val: "测试5" },
{ id: 11, val: "测试6" },
{ id: 5, val: "测试7" },
{ id: 12, val: "测试8" },
],
"2021C": [
{ id: 1, val: "测试9" },
{ id: 6, val: "测试10" },
{ id: 7, val: "测试11" },
{ id: 17, val: "测试12" },
],
"2021D": [
{ id: 13, val: "测试13" },
{ id: 4, val: "测试14" },
{ id: 8, val: "测试15" },
{ id: 9, val: "测试16" },
],
"2021E": [
{ id: 13, val: "测试13" },
{ id: 4, val: "测试14" },
{ id: 8, val: "测试15" },
{ id: 9, val: "测试16" },
],
"2021F": [
{ id: 1, val: "测试13" },
{ id: 6, val: "测试14" },
{ id: 12, val: "测试15" },
{ id: 18, val: "测试16" },
{ id: 24, val: "测试16" },
],
},
tableHerd: [],
ArrList: [],
};
},
methods: {
setList() {
let List = [];
this.tableHerd = [];
for (let key in this.Mock) {
// 获得每列的表头
this.tableHerd.push(key);
// 属性值添加到 List 数组中,为了后面方便遍历每一列的数据。
List.push(this.Mock[key]);
}
// 二维数组打平
let Arrflat = List.flat(2);
// 将项目编码单独拿出
let ArrIndex = Arrflat.map((item) => {
return item.id;
});
// 数组去重,获得每行首列的项目编码
let ArrList = ArrIndex.filter((item, index) => {
return ArrIndex.indexOf(item) === index;
});
// 设置每行的数据
let Arritem = [];
for (let item of ArrList) {
// 设置每行的项目ID
let obj = { item_id: item };
/**
* 遍历每个属性名,
* 查找该属性名对应的属性值数组中是否有与该项目编码相同的元素。
* 如果有,则将该属性值赋给 obj 对象的该属性名中,
* 否则将该属性值设置为 null。
*/
for (let key in this.Mock) {
let find = this.Mock[key].find((items) => {
return items.id === item;
});
// 将属性名逐个赋值给 obj,并初始化属性值
if (find != undefined) {
obj[key] = find.val;
} else {
obj[key] = null;
}
}
Arritem.push(obj);
}
this.ArrList = Arritem;
},
},
mounted() {
this.setList();
},
};
</script>
注:本篇文章仅为记录初学者解决问题的小记录。各位大佬勿喷,如果代码中有可以优化的地方,请各位大佬帮忙指出。谢谢!