通过处理原始数据实现纵向表格

766 阅读3分钟

背景

应届前端菜鸡一个,非计算机专业,想记录自己成长的点点滴滴,才开始写作博文,写的不好求指点。

起因

后端同学(下文称A)问我在纵向展示表单数据怎么做(还给我看了个数据展示列表,如下图,我一懵,这玩意用横向不也很好吗,然后后他来了句 产品要求)

那行吧,由于我现在工作的这家公司主要负责的业务是jquery相关的维护工作,所以我不假思索的就说,jquery一把梭直接html+=''拼接tr,th。

image.png

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展示中,

image.png

      <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,
    });
  }

这里我们假定原始数据必定存在,并且每一个对象字段都相同,那么遍历第一个对象的字段提取并赋给一个新的数组,每个字段都生存一个对应的对象。生成后的新数组控制台打印如下

image.png

填充每个对象对应key值的属性,并以id作为新的key值标识

那么就需要往这个新的数组里面填充每个对象的特有数据作为key值,这里我选择的是id属性。

  newData.map((item) => {
    this.originData.map((e) => {
      item[e.id] = e[item.type];
    });
  });

如此,就可以把每个对象对应的type属性存入,并且以id为key,不会保证重复或者覆盖。 最后生成结果如下

image.png

大功告成

image.png

不过,这是建立在我们展示的数据是固定死的基础上,我从页面构建的角度上看来,这个地方也肯定会呗固定死,如果不是那么可以遍历对应数组生成一个遍历的类型数组

      // 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去做一个假的表格,外观是表格的那种。

拓展

在这个数据中,可能会出现各种问题,比如数据中某个字段是个对象或者是个数组,那么可以先进行数据扁平化,然后再使用我发的方法。