【Vue+el-element】表格相同数据合并单元格

博客第二天纪念日—被表格玩的一天开始了(꒦_꒦)
今天挑战表格相同数据合并单元格,其他列不同数据添加到一行显示

  1. 官方–方法

element中有表格合并的方法:
通过给table传入span-method方法可以实现合并行或列。详见链接: element表格.

  1. 全场最佳–方法

but我们今天要用到的是另一种处理数据的方法:将拿到的table数据循环两次,判断第一次循环拿到的name和第二次循环拿到的name是否相等,如果相等,将当前循环到的其他字段的数据添加到对应数据的后面,并显示出数据。最后整张表进行去重操作。如图所示:贴出代码,仅供参考
在这里插入图片描述
下面展示一些 内联代码片


    data() {
        return {
            tableData: [
                {
                    name: '虎子',
                    sort: '数学:66'
                },
                {
                    name: '虎子',
                    sort: '语文:66'
                },
                {
                    name: '虎子',
                    sort: '英语:66'
                },
                {
                    name: '胖丫',
                    sort: '历史:99'
                },
                {
                    name: '胖丫',
                    sort: '地理:99'
                },
                {
                    name: '翠花',
                    sort: '物理:10'
                },
                {
                    name: '铁柱',
                    sort: '化学:20'
                },
                {
                    name: '旺财',
                    sort: '生物:30'
                },
                {
                    name: '旺财',
                    sort: '数学:40'
                }
            ]
        };
    },
    created() {
        this.setrowspans();
    },
    methods: {
        setrowspans() {
            let resData = JSON.parse(JSON.stringify(this.tableData));
            for (let i = 0; i < resData.length; i ++) {
                const v1 = resData[i];
                for (let j = 0; j < this.tableData.length; j ++) {
                    const v2 = this.tableData[j];
                    // 拿第一次循环的name和第二次循环的name 对比,若相同并且sort不同
                    if ((v1.name === v2.name)
                                && v1.sort !== v2.sort) {
                        // 让v1的sort追加成v1,v2形式
                        let str = JSON.parse(JSON.stringify(`${v1.sort},${v2.sort}`));
                        v1.sort = str;
                    }
                }
            }
            // 根据name去除,优先显示前面的索引
            resData = resData.filter((item, index, self) =>
                index === self.findIndex((t) =>
                    (t.name === item.name)
                ));
            this.tableData = resData;
        }
    }
  1. 不知道是谁的–方法

若要实现下图所示结果,下面展示方法。在这里插入图片描述


    created() {
        this.setrowspans();
    },
    methods: {
        // eslint-disable-next-line no-unused-vars
        objectSpanMethod({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 0) {
                return {
                    rowspan: row.rowspan,
                    colspan: 1
                };
            }
        },
        setrowspans() {
            this.tableData.forEach((v) => {
                v.rowspan = 1;
            });
            for (let i = 0; i < this.tableData.length; i ++) {
                for (let j = i + 1; j < this.tableData.length; j ++) {
                    if (this.tableData[i].name === this.tableData[j].name) {
                        this.tableData[i].rowspan ++;
                        this.tableData[j].rowspan --;
                    }
                }
                // 跳过重复的数据
                i = i + this.tableData[i].rowspan - 1;
            }
        }

详情参考文章链接: 合并表格相同数据.

要在 Element UI 的 `el-table` 中合并相同数据的单元,主要依赖于 `span-method` 属性。该属性允许开发者自定义单元的跨行或跨列显示逻辑。以下是详细的解决方案: ### 实现步骤 #### 1. 准备数据 假设我们有一组如下所示的数据: ```javascript tableData: [ { id: '1', name: '王小虎', amount1: '165', amount2: '3.2', amount3: 10 }, { id: '1', name: '王小虎', amount1: '162', amount2: '4.43', amount3: 12 }, { id: '1', name: '王we虎', amount1: '621', amount2: '1.9', amount3: 9 }, { id: '2', name: '王we虎', amount1: '621', amount2: '2.2', amount3: 17 }, { id: '3', name: '王小虎', amount1: '621', amount2: '4.1', amount3: 15 } ], ``` 为了实现合并功能,我们需要遍历数据并计算每一列中连续相同的值的数量。 --- #### 2. 计算合并规则 创建一个方法用于生成合并所需的跨度数组。以下是一个示例函数: ```javascript methods: { getSpanArr(data) { let spanArr = []; data.forEach((item, index) => { if (index === 0) { spanArr.push(1); } else { if (data[index].id === data[index - 1].id && item.name === data[index - 1].name) { spanArr[spanArr.length - 1]++; spanArr.push(0); } else { spanArr.push(1); } } }); return spanArr; } } ``` 在此基础上,我们可以扩展到其他字段(如 `amount1`, `amount2` 等)。对于每列都需要类似的处理逻辑。 --- #### 3. 定义 `spanMethod` 在 `<el-table>` 组件中绑定 `span-method` 属性,并传入一个函数来控制单元的合并行为。 ```html <el-table :data="tableData" border style="width: 100%" :span-method="objectSpanMethod"> </el-table> ``` 对应的 JavaScript 方法如下: ```javascript computed: { objectSpanMethod() { const spanArrId = this.getSpanArr(this.tableData.map(item => ({ id: item.id, name: item.name }))); const spanArrAmount1 = this.getSpanArr(this.tableData.map(item => item.amount1)); return function({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0 || columnIndex === 1) { // 假设第0列和第1列为需要合并的部分 const _row = spanArrId[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col }; } else if (columnIndex === 2) { // 假设第2列为另一个需要合并的部分 const _row = spanArrAmount1[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col }; } }; } }, ``` 在这里,`getSpanArr` 被多次调用以分别针对不同的列生成合并规则。最终通过 `objectSpanMethod` 返回具体的行列跨越配置。 --- #### 4. 渲染表格列 按照常规方式渲染表头即可。例如: ```html <el-table-column prop="id" label="ID" width="80"></el-table-column> <el-table-column prop="name" label="姓名" width="120"></el-table-column> <el-table-column prop="amount1" label="金额1" width="120"></el-table-column> <el-table-column prop="amount2" label="金额2" width="120"></el-table-column> <el-table-column prop="amount3" label="金额3" width="120"></el-table-column> ``` --- ### 示例代码总结 完整的 Vue 部分代码如下: ```javascript export default { data() { return { tableData: [ { id: '1', name: '王小虎', amount1: '165', amount2: '3.2', amount3: 10 }, { id: '1', name: '王小虎', amount1: '162', amount2: '4.43', amount3: 12 }, { id: '1', name: '王we虎', amount1: '621', amount2: '1.9', amount3: 9 }, { id: '2', name: '王we虎', amount1: '621', amount2: '2.2', amount3: 17 }, { id: '3', name: '王小虎', amount1: '621', amount2: '4.1', amount3: 15 } ] }; }, methods: { getSpanArr(data) { let spanArr = []; data.forEach((item, index) => { if (index === 0) { spanArr.push(1); } else { if (JSON.stringify(data[index]) === JSON.stringify(data[index - 1])) { spanArr[spanArr.length - 1]++; spanArr.push(0); } else { spanArr.push(1); } } }); return spanArr; } }, computed: { objectSpanMethod() { const spanArrIdName = this.getSpanArr( this.tableData.map(item => ({ id: item.id, name: item.name })) ); const spanArrAmount1 = this.getSpanArr(this.tableData.map(item => item.amount1)); return function({ row, column, rowIndex, columnIndex }) { if ([0, 1].includes(columnIndex)) { const _row = spanArrIdName[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col }; } else if (columnIndex === 2) { const _row = spanArrAmount1[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col }; } }; } } }; ``` --- ### 注意事项 - 数据需按一定顺序排列才能正确合并。如果原始数据无序,则应先对其进行排序。 - 当涉及多个字段时,可能需要额外的逻辑来区分哪些字段应该参与合并[^1]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值