使用el-table将二维表格“展平”成一维表格

3 阅读1分钟

将一个4行3列的表格,转换成2行6列显示,例如:

```

A B C

D E F

G H I

J K L

```

转换后:

```

A B C D E F

G H I J K L

```

FlattenTable.vue

<script>export default {  props: {    datas: {      type: Array,      required: true,    },    rowItemSize: {      type: Number,      default: 1,    },  },  computed: {    itemsResult() {      const len = this.datas.length;      const rowSize = this.rowItemSize;      return Math.max(1, Math.min(len, rowSize));    },    tableRows() {      const chunks = this.chunkArray(this.datas, this.itemsResult);      const paddedRows = [];      chunks.forEach(group => {        paddedRows.push(group);      });      return paddedRows;    },  },  methods: {    chunkArray(arr, size, filler = {}) {      const result = [];      for (let i = 0; i < arr.length; i += size) {        const chunk = arr.slice(i, i + size);        if (chunk.length < size) {          const padding = Array(size - chunk.length).fill(filler);          chunk.push(...padding);        }        result.push(chunk);      }      return result;    },  },  render(h) {    const slots = this.$slots.default || [];    const itemsResult = this.itemsResult;    const slotNodes = [];    for (let i = 0; i < itemsResult; i++) {      const col = i % itemsResult;      slotNodes.push(        ...slots.map(vnode => {          const Ctor = vnode.componentOptions.Ctor;          const v = vnode.componentOptions.propsData;          const props = { ...v, prop: `[${col}].${v.prop}` };          const scopedSlots = vnode.data.scopedSlots;          return h(Ctor, {            props,            on: vnode.componentOptions.listeners,            attrs: vnode.componentOptions.attrs,            scopedSlots: scopedSlots && {              ...scopedSlots,              default: props => {                return scopedSlots.default({                  ...props,                  row: props.row[col],                  dataIndex: itemsResult * props.$index + i,                });              },            },          });        })      );    }    return h(      "el-table",      {        props: { data: this.tableRows, ...this.$attrs },        on: this.$listeners,      },      slotNodes    );  },};</script>

index.vue

<template>  <flatten-table v-if="lineStat.length" size="mini" :datas="lineStat" :row-item-size="rowItemSize">    <el-table-column label="" min-width="120" prop="label">      <template slot-scope="scope">        <div v-if="scope.row.name">          <div class="rect"></div>          <div>{{ scope.row.name }} {{ scope.dataIndex }}</div>        </div>      </template>    </el-table-column>    <el-table-column label="max" width="60" prop="data.max" />    <el-table-column label="avg" width="60" prop="data.avg" />  </flatten-table></template><script>import FlattenTable from "./FlattenTable";export default {  components: { FlattenTable },  props: {    data: {      type: Array,      required: true,    },  },  data() {    return {      lineStat: [],      tableData: [        { name: "g1", data: { max: 11, avg: 12 } },        { name: "g2", data: { max: 21, avg: 22 } },        { name: "g3", data: { max: 31, avg: 32 } },      ],    };  },};</script>

支持参数 rowItemSize,表示一行可以展平多少原始行

另外在作用域插槽加了一个参数 dataIndex,表示原始行下标