el-table 多行合并 手动添加虚拟行

<template>
    <el-table :data="allData" border ref="table" :cell-style="{ 'text-align': 'center' }" :header-cell-style="{
        background: '#5f697d',
        color: '#fff',
        height: '10px',
        'text-align': 'center'
    }" stripe :span-method="spanMethod">
        <el-table-column prop="orderId" label="订单号">
            <template #default="{ row, $index }">
                <div @click="showItems($index)">{{ row.orderId }} </div>
            </template>
        </el-table-column>

        <el-table-column label="信息A">
            <template #default="{ row }">
                <div v-if="row.isVirtual" style="height:100px">
                    <div style="display: flex;flex-direction: column;">
                        <el-input v-model="row.inputValue" placeholder="请输入内容" />
                        <div v-if="row.itemsListShow">hhhhhhhhhhh</div>
                    </div>

                </div>
                <div v-else>
                    {{ row.infoA }}
                </div>
            </template>
        </el-table-column>

        <el-table-column label="信息B">
            <template #default="{ row }">
                <div v-if="row.isVirtual">

                </div>
                <div v-else>
                    {{ row.infoB }}
                </div>
            </template>
        </el-table-column>
    </el-table>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';

// 原始数据
const originalData = [
    { orderId: '1001', infoA: '张三', infoB: '李四', ORDER_PRO: [{ chirldrenId: "11", chirldrenname: "11" }, { chirldrenId: "22", chirldrenname: "22" }] },
    { orderId: '1002', infoA: '王五', infoB: '赵六', ORDER_PRO: [{ chirldrenId: "13", chirldrenname: "13" }] },
    { orderId: '1003', infoA: '钱七', infoB: '孙八', ORDER_PRO: [] },
];

const showItems = (row) => {
    console.log(row)
    allData.value[row + 1].itemsListShow = !allData.value[row + 1].itemsListShow
}



// 显示数据
const allData = ref();
// 添加虚拟行后的扁平数组
const flattenedData = () => {
    const result = [];
    originalData.forEach((item) => {
        // 正常行
        result.push({ ...item, itemsListShow: false });
        // 虚拟行:保留订单号,添加输入字段
        result.push({
            isVirtual: true,
            orderId: item.orderId,
            inputValue: '',
            ORDER_PRO: item.ORDER_PRO,
            itemsListShow: false,
        });
    });
    allData.value = result;
};
onMounted(() => {
    flattenedData();
});
// 合并方法:
const spanMethod = (params) => {
    const { row, rowIndex, columnIndex } = params;

    if (columnIndex === 0) { // 对于订单号列
        if (rowIndex % 2 === 0) { // 真实数据行
            return { rowspan: 2, colspan: 1 }; // 合并两行
        } else { // 虚拟行
            return { rowspan: 0, colspan: 0 }; // 隐藏该单元格
        }
    }

    if (row.isVirtual && columnIndex === 1) { // 对于虚拟行中的信息A列
        return { rowspan: 1, colspan: 2 }; // 合并后两列
    }

    if (row.isVirtual && columnIndex === 2) { // 对于虚拟行中的信息B列
        return { rowspan: 0, colspan: 0 }; // 隐藏该列
    }

    return { rowspan: 1, colspan: 1 };
};
</script>

 效果:三行数据   但是相当于6行数据每一行的第二行是一个虚拟的合并数据

### Element Plus `el-table` 组件实现多行合并Element Plus框架中的`el-table`组件支持通过自定义函数来控制哪些单元格应该被合并。对于基于特定属性值相同的合并的情况,可以利用`span-method`属性提供的回调函数。 当表格数据加载完毕后,在遍历每一的数据时判断相邻之间指定字段的内容是否相等;如果相等,则设置当前该列的高度跨越数(rowSpan),并将下一对应位置设为0表示隐藏[^1]。 下面是一个简单的例子用于说明如何根据某个属性(例如name)来进的自动合并: ```html <template> <div style="margin: 20px;"> <el-table :data="tableData" border :span-method="objectSpanMethod"> <el-table-column prop="date" label="日期"></el-table-column> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="amount1" label="数值 1"></el-table-column> <el-table-column prop="amount2" label="数值 2"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> </div> </template> <script setup lang="ts"> import { ref } from 'vue' const tableData = [ { date: "2016-05-03", name: "Tom", amount1: "1", amount2: "2", address: "No. 189, Grove St, Los Angeles" }, { date: "2016-05-02", name: "Tom", // 和上一条记录的名字一样 amount1: "2", amount2: "3", address: "No. 189, Grove St, Los Angeles" } ] // 定义一个对象用来存储每组连续相同项的数量 let countMap = new Map() function objectSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 1) { // 只处理第二列即'name'这一列 const currentValue = row[column.property]; let prevValue; if(rowIndex !== 0){ prevValue = tableData[rowIndex - 1][column.property]; } if(currentValue===prevValue){ // 如果当前值等于前一值则返回{ rowspan: 0, colspan: 0 },意味着这不会显示出来 return { rowspan: 0, colspan: 0 }; }else{ // 否则计算有多少个连续相同的元素并更新countMap映射表 let nextIndex=rowIndex+1; while(nextIndex<tableData.length && tableData[nextIndex][column.property]==currentValue){ nextIndex++; } countMap.set(`${rowIndex}-${columnIndex}`,nextIndex-rowIndex); return { rowspan: nextIndex-rowIndex , colspan: 1}; } } } </script> ``` 此代码片段展示了怎样创建一个具有合并功能的表格,并且指定了具体的逻辑去决定何时以及如何合并某些下的单元格。注意这里只针对"name"这个字段做了特殊处理,实际应用中可以根据需求调整条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值