vue表格合并单元格

需求

vue表格同列不一样行的相同内容合并单元格,直接看图更直观。vue

原表格 bash

效果

很明显,后一列的合并项受前一项的合并项的限制。数据结构

实现

废话很少说,直接上代码less

<template>
  <div class="table_box">
    <table class="table">
      <thead>
        <tr>
          <th>序号</th>
          <th>名字</th>
          <th>性别</th>
          <th>年龄</th>
          <th>地址</th>
          <th>兴趣</th>
          <th>电话</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in data" :key="index">
          <td>{{index}}</td>
          <td ref="td">{{item.name}}</td>
          <td ref="td">{{item.sex}}</td>
          <td ref="td">{{item.age}}</td>
          <td ref="td">{{item.address}}</td>
          <td ref="td">{{item.habit}}</td>
          <td ref="td">{{item.tel}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
     data: [
       {name: '小明', sex: '男', age: '24', address: '湖北', habit: '篮球', tel: '15927001701'},
       {name: '小明', sex: '男', age: '24', address: '湖北', habit: '篮球', tel: '15927001702'},
       {name: '小明', sex: '男', age: '24', address: '湖北', habit: '足球', tel: '15927001703'},
       {name: '小明', sex: '男', age: '24', address: '湖南', habit: '篮球', tel: '15927001704'},
       {name: '小明', sex: '男', age: '23', address: '湖南', habit: '篮球', tel: '15927001705'},
       {name: '小明', sex: '男', age: '23', address: '湖北', habit: '篮球', tel: '15927001706'},
       {name: '小明', sex: '男', age: '24', address: '湖北', habit: '篮球', tel: '15927001707'},
       {name: '小明', sex: '女', age: '24', address: '湖北', habit: '篮球', tel: '15927001708'},
       {name: '小红', sex: '女', age: '24', address: '湖北', habit: '篮球', tel: '15927001709'},
       {name: '小红', sex: '女', age: '24', address: '湖南', habit: '篮球', tel: '15927001700'}
     ]
    }
  },
  mounted() {
    this.merge()
  },
  methods: {
    merge() 
      // 若是数据是乱序,整理顺序,按本身的数据结构排序
      // this.data.sort((a,b) => {
      //   return JSON.stringify(a) >=JSON.stringify(b)?1:-1;
      // })
      // console.log(this.data)
      this.$nextTick(() => {
        var tds = this.$refs.td;
        console.log(tds)
        let  n=0; // 每次合并单元格从第几行开始合并
        for(let col=0,collen=6; col<collen;col++) {
          n=0;
          for(let row=0,len=this.data.length; row<len;row++) {
            if(n!=row && tds[col+n*collen].innerHTML == tds[col+row*collen].innerHTML) {
              if(col!=0) {
                if(tds[col+row*collen-1].rowSpan == 0){ // 前一列被合并,才能进行此列合并
                  tds[col+n*collen].rowSpan = tds[col+n*collen].rowSpan + 1;
                  tds[col+row*collen].rowSpan = 0;
                  tds[col+row*collen].hidden = true;
                }else {
                  n=row;  // 合并停止,重置开始合并行
                }
              }else {
                  tds[col+n*collen].rowSpan = tds[col+n*collen].rowSpan + 1;
                  tds[col+row*collen].rowSpan = 0;
                  tds[col+row*collen].hidden = true;
              }
            }else {
              n=row;  // 合并停止,重置开始合并行
            }
          }
        }
      })
      
    }
  }

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.table_box{
  .table{
    border: 1px solid #cccccc;
    border-collapse: collapse;
    th{
      // align-items: center;
      padding: 10px 20px;
      border: 1px solid #cccccc;
      text-align: left;
    }
    td{
      padding: 10px 20px;
      border: 1px solid #cccccc;
      text-align: left;
    }
  }
}
</style>

复制代码
相关文章
相关标签/搜索