elementui中table组件合并行(看就懂)

做一个动态合并的table表格, 如下图

1.首先定义需要合并的字段及合并后的对象
data(){
   return {
      mergeFields: ['name', 'amount3'],
      mergeObj: {}
   }
}
2.分配合并项函数, data为数据源
        //获取合并序号
        getSpanArr(data = []) {
            this.mergeFields.forEach(key => {
                // 用来记录合并行的起始位置
                let count = 0
                // 记录每一列的合并信息
                this.mergeObj[key] = []
                data.forEach((item, index) => {
                    // 第一行直接 push 一个 1
                    if (!index) {
                        this.mergeObj[key].push(1)
                        return
                    }

                    // 判断当前行是否与上一行其值相等 
                    // 如果相等在count记录的位置其值+1 
                    // 表示当前行需要合并 并添加一个 0 占位
                    if (item[key] === data[index - 1][key]) {
                        this.mergeObj[key][count] += 1
                        this.mergeObj[key].push(0)
                        return
                    }

                    // 如果当前行和上一行其值不相等 记录当前位置
                    count = index 
                    // 重新push一个1
                    this.mergeObj[key].push(1) 
                })
            })
        },

        //合并行
        objectSpanMethod({ row, column, rowIndex, columnIndex }) {
            if (!this.mergeFields.includes(column.property)) return

            // 判断其值是不是为0
            if (this.mergeObj[column.property][rowIndex]) {
                return [this.mergeObj[column.property][rowIndex], 1]
            }

            // 如果为0则为需要合并的行
            return [0, 0]
        },
3.数据内容改变时函数
        //改变百分比触发
        changeVal(val, row, idx) {
            //找到一级相同项
            let alikeList = this.tableData.filter(it => it.name == row.name)
            //汇总
            let allPercent = alikeList.reduce((acc, curr) => {
                return acc + curr.amount2
            }, 0)
            //改变每一项
            let list = JSON.parse(JSON.stringify(this.tableData))
            list.forEach(it => {
                if (it.name == row.name) {
                    it.amount3 = allPercent
                }
            })
            //先分配需要合并项
            this.getSpanArr(list)
            this.$nextTick(() => {
                this.tableData = JSON.parse(JSON.stringify(list))
            })
        }
4.完整代码

<template>
    <div class="wokeRate">
        <el-table :data="tableData" :span-method="objectSpanMethod" :border="true" size="small">
            <el-table-column v-for="item in fields" :key="item.key" :prop="item.key" :label="item.label"
                :width="item.width">
                <template slot-scope="scope">
                    <div class="it" v-if="item.type == 'text'">{{ scope.row[item.key] }}</div>
                    <div class="it" v-if="item.type == 'input'">
                        <el-input-number size="mini" v-model="scope.row[item.key]" :placeholder="`请输入${item.label}`"
                            @change="e => changeVal(e, scope.row, scope.$index)"></el-input-number>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script>
export default {
    name: 'DfcvDtmsVueWokeRate',
    data() {
        return {
            mergeFields: ['name', 'amount3'],
            mergeObj: {},
            tableData: [
                {
                    name: '维保',
                    amount1: '维保',
                    amount2: 0,
                    amount3: 0
                }, {
                    name: '等待样品',
                    amount1: '等待样机',
                    amount2: 0,
                    amount3: 0
                }, {
                    name: '等待样品',
                    amount1: '等待样件',
                    amount2: 0,
                    amount3: 0
                },
                {
                    name: '无任务',
                    amount1: '无任务',
                    amount2: 0,
                    amount3: 0
                }
            ],
            fields: [
                {
                    label: '一级',
                    key: 'name',
                    type: 'text'
                },
                {
                    label: '二级',
                    key: 'amount1',
                    type: 'text'
                },
                {
                    label: '百分比(%)',
                    key: 'amount2',
                    type: 'input'
                },
                {
                    label: '汇总(%)',
                    key: 'amount3',
                    type: 'text'
                }
            ]
        }
    },

    mounted() {
        this.getSpanArr(this.tableData)
    },

    methods: {
        //获取合并序号
        getSpanArr(data = []) {
            this.mergeFields.forEach(key => {
                // 用来记录需要合并行的起始位置
                let count = 0
                // 记录每一列的合并信息
                this.mergeObj[key] = []
                data.forEach((item, index) => {
                    // 第一行直接 push 一个 1
                    if (!index) {
                        this.mergeObj[key].push(1)
                        return
                    }

                    // 判断当前行是否与上一行其值相等 
                    // 如果相等在count记录的位置其值+1 
                    // 表示当前行需要合并 并添加一个 0 占位
                    if (item[key] === data[index - 1][key]) {
                        this.mergeObj[key][count] += 1
                        this.mergeObj[key].push(0)
                        return
                    }

                    // 如果当前行和上一行其值不相等 记录当前位置
                    count = index
                    // 重新push一个 1
                    this.mergeObj[key].push(1)
                })
            })
        },

        //合并行
        objectSpanMethod({ row, column, rowIndex, columnIndex }) {
            if (!this.mergeFields.includes(column.property)) return

            // 判断其值是不是为0
            if (this.mergeObj[column.property][rowIndex]) {
                return [this.mergeObj[column.property][rowIndex], 1]
            }

            // 如果为0则为需要合并的行
            return [0, 0]
        },

        //改变百分比触发
        changeVal(val, row, idx) {
            //找到一级相同项
            let alikeList = this.tableData.filter(it => it.name == row.name)
            //汇总
            let allPercent = alikeList.reduce((acc, curr) => {
                return acc + curr.amount2
            }, 0)
            //改变每一项
            let list = JSON.parse(JSON.stringify(this.tableData))
            list.forEach(it => {
                if (it.name == row.name) {
                    it.amount3 = allPercent
                }
            })
            //先分配需要合并项
            this.getSpanArr(list)
            this.$nextTick(() => {
                this.tableData = JSON.parse(JSON.stringify(list))
            })
        }
    }
}
</script>

<style lang="scss" scoped>
.wokeRate {
    width: 100%;
    padding: 20px 0;

    .el-table {
        margin-top: 20px;
    }
}
</style>
elementPlus一样使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Element UITable 组件合并列后高变高的问题可以通过自定义单元格的样式来解决。以下是一种可能的解决方案: 1. 在需要合并列的单元格,使用自定义的样式来控制高。可以通过设置 `line-height` 属性来调整高,将其设置为合适的值。 2. 在 Table 组件,可以使用 `cell-style` 属性来设置单元格的样式。通过这个属性,你可以为每个单元格设置自定义的样式。 下面是一个示例代码,展示如何使用自定义样式来解决合并列后高变高的问题: ```html <template> <el-table :data="tableData"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> <el-table-column prop="mergedCell" label="合并列" :formatter="mergeCellFormatter"></el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 18, address: '北京', mergedCell: '合并列内容' }, { name: '李四', age: 20, address: '上海', mergedCell: '' }, { name: '王五', age: 22, address: '广州', mergedCell: '' }, ], }; }, methods: { mergeCellFormatter(row, column, cellValue, index) { // 判断当前单元格是否需要合并 if (index === 0) { return { rowspan: 3, // 合并列的数 style: 'line-height: 60px;', // 设置高 content: cellValue, // 单元格内容 }; } else { return { rowspan: 0, // 不合并列 content: '', // 空内容 }; } }, }, }; </script> ``` 在上述示例,我们通过 `mergeCellFormatter` 方法来控制合并列的样式和内容。通过设置 `rowspan` 属性来指定合并列的数,同时设置 `style` 属性来调整高。 注意:上述示例仅为示意,实际使用时需要根据你的具体需求进调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值