基于Vue2+elementUi实现树形 横向 合并 table不规则表格

发布于:2025-08-30 ⋅ 阅读:(18) ⋅ 点赞:(0)

1、实现效果

共N行,但是每一列对应的单元格列数固定,行数不固定
在这里插入图片描述

2、实现方式

说明:使用的是vue2 + elementUI表格组件 + js实现

 <template>
    <div class="table-container" >
        
        <el-table  height="100%" :span-method="spanMethod" :data="tableTemData" :cell-style="cellStyle" border :show-header="false">
            <el-table-column align="center" prop="name" label="" />
            <el-table-column align="center" prop="name2" label="时间" />
            <el-table-column align="center" prop="name3" label="" />
            <el-table-column align="center" prop="name4" label="8:00" />
        </el-table>
        

    </div>
  </template>
  <script>
  export default {
    data() {
      return {
        //所需数据格式
        tableData: [
            { name: '集控中心', name2: '器器器1', name3: '电压A', name4: '8:00', name5: '1111', rowspan_0: 11, rowspan_1: 4,rowspan_2: 1 },
            { name: '集控中心', name2: '器器器1', name3: '电压B', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器1', name3: '电压C', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器1', name3: '电压D', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器2', name3: '电压E', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 2, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器2', name3: '电压F', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器3', name3: '电压G', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 3, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器3', name3: '电压H', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
            { name: '集控中心', name2: '器器器3', name3: '电压I', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 2 },
            { name: '集控中心', name2: '器器器4', name3: '电压J', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 2, rowspan_2: 0 },
            { name: '集控中心', name2: '器器器4', name3: '电压K', name4: '8:00', name5: '1111', rowspan_0: 0, rowspan_1: 0, rowspan_2: 1 },
        ],
        //原数据格式
        treeData: [
            {
            name: '单位B-A',
            children: [
                {
                    name2: '视频',
                    children: [{ name3: '0000s', children:[{name4: '5G'},{name4: '有线网'}] }]
                },
                {
                    name2: '视频',
                    children: [
                        { name3: ':0000s',children: [{name4: '5G'},{name4: '有线网'}] },
                        { name3: ':0000s', children:[{name4: '5G'},{name4: '有线网'}] }
                    ]
                },
                {
                    name2: '视频3',
                    children: [
                        { name3: '0000s', children:[{name4: '5G'},{name4: '有线网'}] },
                        { name3: '8976s', children:[{name4: '5G'},{name4: '有线网'}] }
                    ]
                }
            ]
            }, {
            name: '单位A-C',
            children: [
                {
                    name2: '5视频1',
                    children: [{ name3: 'xxx', children:[{name4: '5G'},{name4: '有线网'}] }]
                },
                {
                    name2: '视频2',
                    children: [
                        { name3: ':0000s',children: [{name4: '5G'},{name4: '有线网'}] },
                        { name3: ':0000s', children:[{name4: '5G'},{name4: '有线网'}] }
                    ]
                }
            ]
            }
        ],
        count: 0,
        tableTemData: [],
        maxArr: []
      };
    },
    mounted() {
      this.tree_To_table(this.treeData, 0);
  },
    methods: {
         tree_To_table(arr, num) {
            arr.forEach((item, index) => {
                //   初始化数量
                this.count = 0
                if (item.children) {
                    // 计算所有所有子集数量
                    this.getnum(item.children)
                    item['rowspan_' + num] = this.count
                    //   深复制后删除children,否则可能会造成死循环
                    let itemVar = JSON.parse(JSON.stringify(item))
                    delete itemVar.children
                    item.children.forEach((m, n) => {
                        //   将除第一行之外的重置为0
                        if (n != 0) {
                            for (let o = 0; o <= num; o++) {
                                itemVar['rowspan_' + o] = 0
                            }
                        }
                        // 合并父子级
                        Object.assign(m, itemVar)
                    })
                    this.tree_To_table(item.children, num + 1)
                } else {
                    item['rowspan_' + num] = 1
                    this.maxArr.push(num)
                    this.tableTemData.push(item)
                }
            })
        
        },
            
        getnum(arr) {
            arr.forEach((item, index) => {
                if (item.children) {
                  this.getnum(item.children)
                } else {
                  this.count += 1
                }
            })
        },
        spanMethod ({ row, column, rowIndex, columnIndex }) {
                let index = this.tableTemData.indexOf(row)
                if (columnIndex < Math.max(...this.maxArr)) {
                    let rowspan = row['rowspan_' + columnIndex]
                    // 这里可以特殊处理:设置第一列横跨所有行
                    // if (rowIndex == 0 && columnIndex == 0) {
                    //    rowspan = this.tableTemData.length
                    // }
                    return {
                        rowspan,
                        colspan: rowspan == 0 ? 0 : 1
                    }
                }
                return {
                    rowspan: 1,
                    colspan: 1
                }
        },
         cellStyle({ row, column, rowIndex, columnIndex }) {
            return {
              backgroundColor: 'rgba(50, 247, 255, 0.08)'
            }
        }
    }
  }
  </script>
<style lang="scss">
.table-container {
  width: 100%;
  overflow-x: auto; /* 横向滚动条,如果内容过宽 */
}

table {
  width: 100%;
  border-collapse: collapse;
}

td {
  border: 1px solid #ccc;
  padding: 8px;
  text-align: center;
  background-color: #f9f9f9;
}
</style>

end~
希望记录的问题能帮助到你