Element 表格动态合并并行或列的方式(span-method)

12,502 阅读1分钟

在项目开发过程,难以避免会有表格动态合并行或列的需求,Elemnent 官网的 demo 是针对静态情况合并的,并不符合我们大部分人的动态需求,故今天整理出一份,我业务逻辑代码里如何处理表格动态合并的资料,

demo 链接

<div id="app">
  <el-table :data="tableData" :span-method="handleSameMerge" style="width: 100%">
    <el-table-column label="序号" width="80">
      <template slot-scope="scope">{{scope.$index}}</template>
    </el-table-column>
    <el-table-column prop="class_label" label="渠道分类" width="180">
    </el-table-column>
    <el-table-column prop="source_label" label="渠道来源" width="180">
    </el-table-column>
  </el-table>
</div>
<script>
new Vue({
    el: '#app',
    data: {
        tableData: [],
        tempIndex: [],
        list: [
            {
                id: 1,
                class_code: 1,
                class_label: '媒体',
                created_at: null,
                updated_at: null,
                source: [
                    {
                        id: 1,
                        source_code: 31,
                        source_label: '电视媒体',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    },
                    {
                        id: 17,
                        source_code: 16,
                        source_label: '地铁广告',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    }
                ]
            },
            {
                id: 2,
                class_code: 1,
                class_label: 'hhh',
                created_at: null,
                updated_at: null,
                source: [
                    {
                        id: 1,
                        source_code: 31,
                        source_label: 'test1',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    },
                    {
                        id: 17,
                        source_code: 16,
                        source_label: 'test2',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    },
                    {
                        id: 17,
                        source_code: 16,
                        source_label: 'test3',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    },
                    {
                        id: 17,
                        source_code: 16,
                        source_label: 'test4',
                        created_at: null,
                        updated_at: null,
                        class_code: '1'
                    }
                ]
            },
            {
                id: 4,
                class_code: 1,
                class_label: 'shiyixia',
                created_at: null,
                updated_at: null

            }
        ]
    },
    watch: {
        list: {
            handler(nv) {
                let arr = [];
                let tempMergeIndex = [];
                let pos;
                nv.forEach((item, i) => {
                    if (item.source && item.source.length) {
                        let sourceArr = item.source.map(_ => {
                            return {
                                ..._,
                                flag: i + '',
                                class_label: item.class_label
                            };
                        });
                        arr.push(...sourceArr);
                    } else {
                        arr.push(item);
                    }
                });
                this.tableData = arr;
                // 处理arr,生成一个与行数相同的数组记录每一行设置的合并数
                for (let i = 0; i < arr.length; i++) {
                    if (i === 0) {
                        tempMergeIndex.push(1);
                        pos = 0;
                    } else {
                        if (arr[i].flag && (arr[i].flag === arr[i - 1].flag)) {
                            tempMergeIndex[pos] += 1;
                            tempMergeIndex.push(0);
                        } else {
                            tempMergeIndex.push(1);
                            pos = i;
                        }
                    }
                }
                this.tempIndex = tempMergeIndex;
            },
            deep: true,
            immediate: true
        }
    },
    methods: {
        // 从 tempIndex 获取当前 row 需要合并的行数
        handleSameMerge({row, column, rowIndex, columnIndex}) {
            if (columnIndex === 1) {
                return {
                    rowspan: this.tempIndex[rowIndex],
                    colspan: 1
                };
            }
        }
    }
});

</script>