背景
应届前端菜鸡一个,非计算机专业,想记录自己成长的点点滴滴,才开始写作博文,写的不好求指点。
起因
后端同学(下文称A)问我在纵向展示表单数据怎么做(还给我看了个数据展示列表,如下图,我一懵,这玩意用横向不也很好吗,然后后他来了句 产品要求)
那行吧,由于我现在工作的这家公司主要负责的业务是jquery相关的维护工作,所以我不假思索的就说,jquery一把梭直接html+=''拼接tr,th。
jquery代码就不放出了,一把梭的代码实在丢人。
然后A又说,我们公司要求的技术栈是elemenui+vue,能通过处理数据来实现纵向表格吗?
注:vue也是我现学的,平时工作都是jquery为主。
思路
纵向表格和横向表格差距在于,一个是纵向展示对象的字段属性,另外一个是横向,而elementui封装el-table是根据每一行的对象中对应props的字段来渲染,那么根结就在于,怎么把对象处理成el-table能够拿到得对象数组格式。
originData: [
{
id: 0,
name: "硫酸",
type: "化工类",
num: "有4个",
average: "3块钱",
people: "技术员工",
},
{
id: 1,
name: "硫酸",
type: "化工类",
num: "有4个",
average: "3块钱",
people: "技术员工",
},
{
id: 2,
name: "语文书",
type: "教育类",
num: "有3个",
average: "3块钱",
people: "小学生",
},
{
id: 3,
name: "计算机",
type: "科研类",
num: "有2个",
average: "10块钱",
people: "中学生",
},
],
提取key值
在正常的el-table展示中,
<el-table-column label="类型" property="type" align="center">
</el-table-column>
label代表了横向的每一个属性字段名,prop则代表了这个属性在对象中的key值,如这里的类型对应type。 那么纵向表格的思路就是,将对象的id或者某个唯一数据作为key值,这个样子渲染的时候就会将同一对象的属性渲染到一竖排了。
let newData = [];
for (let k in this.originData[0]) {
newData.push({
type: k,
});
}
这里我们假定原始数据必定存在,并且每一个对象字段都相同,那么遍历第一个对象的字段提取并赋给一个新的数组,每个字段都生存一个对应的对象。生成后的新数组控制台打印如下
填充每个对象对应key值的属性,并以id作为新的key值标识
那么就需要往这个新的数组里面填充每个对象的特有数据作为key值,这里我选择的是id属性。
newData.map((item) => {
this.originData.map((e) => {
item[e.id] = e[item.type];
});
});
如此,就可以把每个对象对应的type属性存入,并且以id为key,不会保证重复或者覆盖。 最后生成结果如下
大功告成
不过,这是建立在我们展示的数据是固定死的基础上,我从页面构建的角度上看来,这个地方也肯定会呗固定死,如果不是那么可以遍历对应数组生成一个遍历的类型数组
// i: [
// {
// label: "物品",
// id: 'type'
// },
// {
// label: "硫酸",
// id: '0'
// },
// {
// label: "硫酸",
// id: '1'
// },
// {
// label: "语文书",
// id: '2'
// },
// {
// label: "计算机",
// id: '3'
// },
// ],
完整代码
<template>
<div class="m50">
<el-table border style="margin-top: 50px" :data="this.data">
<!-- <el-table-column v-for="item in i" :key="item.label" :label="item.label" :property="item.id" align="center"> -->
</el-table-column>
<!-- <el-table-column label="名称" prop="name" align="center"> </el-table-column> -->
<!-- <el-table-column label="类型" prop="type" align="center"> </el-table-column> -->
<!-- <el-table-column label="数量" prop="num" align="center"> </el-table-column> -->
<!-- <el-table-column label="均价" prop="average" align="center"> </el-table-column> -->
<el-table-column label="物品" prop="type" align="center"> </el-table-column>
<el-table-column label="硫酸" prop="0" align="center"> </el-table-column>
<el-table-column label="硫酸" prop="1" align="center"> </el-table-column>
<el-table-column label="语文书" prop="2" align="center"> </el-table-column>
<el-table-column label="计算机" prop="3" align="center"> </el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
// i: [
// {
// label: "物品",
// id: 'type'
// },
// {
// label: "硫酸",
// id: '0'
// },
// {
// label: "硫酸",
// id: '1'
// },
// {
// label: "语文书",
// id: '2'
// },
// {
// label: "计算机",
// id: '3'
// },
// ],
originData: [
{
id: 0,
name: "硫酸",
type: "化工类",
num: "有4个",
average: "3块钱",
people: "技术员工",
},
{
id: 1,
name: "硫酸",
type: "化工类",
num: "有4个",
average: "3块钱",
people: "技术员工",
},
{
id: 2,
name: "语文书",
type: "教育类",
num: "有3个",
average: "3块钱",
people: "小学生",
},
{
id: 3,
name: "计算机",
type: "科研类",
num: "有2个",
average: "10块钱",
people: "中学生",
},
],
data: [],
};
},
created() {
this.data = this.getData();
},
filters: {
capitalize: function (value) {
if (!value) return "";
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
},
},
methods: {
getData() {
let newData = [];
for (let k in this.originData[0]) {
newData.push({
type: k,
});
}
// this.i = deepCopy(obj)
newData.map((item) => {
this.originData.map((e) => {
item[e.id] = e[item.type];
});
});
console.log(newData);
return newData;
},
},
};
</script>
总结
其实感觉没啥太大的用处,如果有生成某个字段的统计数组可以这个样子渲染会非常直接生成。 如果真的有这种需求,我个人认为更好的解决办法是使用div去做一个假的表格,外观是表格的那种。
拓展
在这个数据中,可能会出现各种问题,比如数据中某个字段是个对象或者是个数组,那么可以先进行数据扁平化,然后再使用我发的方法。