Bootstrap

vue js table colspan rowspan

需求,要写一个菜单权限表。需要做到单元格合并,本来用的antd-vue的表格,然后构造customRender,总感觉有点本末倒置,其实自己实现,更快,而且想改哪里,改哪里。下面是写这个功能前的测试demo。
效果图
请添加图片描述
代码

<template>
  <div class="class-table">
    <div class="table-wrapper">
      <div class="tabel-container">
        <table>
          <thead>
            <tr>
              <th v-for="(week, index) in weeks" :key="index">{{ '周' + digital2Chinese(index + 1, 'week') }}</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in classTableData" :key="index">
              <td v-for="(week, index) in weeks" :key="index" :colspan="item[week].colspan" :rowspan="item[week].rowspan" v-show="item[week].colspan !== 0 && item[week].rowspan !== 0">
                {{ item[week].name || '-' }}
                <div style="margin-top: 5px">{{ item[week].colspan }}{{ item[week].rowspan }}</div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      weeks: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
      classTableData: [
        {
          classesTime: '08:00-09:00',
          monday: { name: 'CSS', rowspan: 1, colspan: 2 },
          tuesday: { name: 'JS', rowspan: 1, colspan: 0 },
          wednesday: { name: 'VUE', rowspan: 1, colspan: 3 },
          thursday: { name: 'JQUERY', rowspan: 1, colspan: 0 },
          friday: { name: 'REACT', rowspan: 1, colspan: 0 },
          saturday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          sunday: { name: 'REACT', rowspan: 2, colspan: 1 },
        },
        {
          classesTime: '09:00-10:00',
          monday: { name: 'DATA', rowspan: 1, colspan: 1 },
          tuesday: { name: 'CSS', rowspan: 1, colspan: 1 },
          wednesday: { name: 'REACT', rowspan: 1, colspan: 1 },
          thursday: { name: 'JS', rowspan: 1, colspan: 1 },
          friday: { name: 'REACT', rowspan: 1, colspan: 1 },
          saturday: { name: 'DATA', rowspan: 1, colspan: 1 },
          sunday: { name: 'REACT', rowspan: 0, colspan: 1 },
        },
        {
          classesTime: '10:00-11:00',
          monday: { name: 'DATA', rowspan: 1, colspan: 1 },
          tuesday: { name: 'CSS', rowspan: 1, colspan: 1 },
          wednesday: { name: 'DATA', rowspan: 1, colspan: 1 },
          thursday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          friday: { name: 'DATA', rowspan: 1, colspan: 1 },
          saturday: { name: 'JS', rowspan: 1, colspan: 1 },
          sunday: { name: 'VUE', rowspan: 1, colspan: 1 },
        },
        {
          classesTime: '11:00-12:00',
          monday: { name: '', rowspan: 1, colspan: 1 },
          tuesday: { name: 'VUE', rowspan: 1, colspan: 1 },
          wednesday: { name: 'CSS', rowspan: 1, colspan: 1 },
          thursday: { name: 'VUE', rowspan: 1, colspan: 1 },
          friday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          saturday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          sunday: { name: 'DATA', rowspan: 1, colspan: 1 },
        },
        {
          classesTime: '13:00-14:00',
          monday: { name: 'DATA', rowspan: 1, colspan: 1 },
          tuesday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          wednesday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          thursday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          friday: { name: '', rowspan: 1, colspan: 1 },
          saturday: { name: 'JS', rowspan: 1, colspan: 1 },
          sunday: { name: 'REACT', rowspan: 1, colspan: 1 },
        },
        {
          classesTime: '14:00-15:00',
          monday: { name: 'REACT', rowspan: 1, colspan: 1 },
          tuesday: { name: 'JS', rowspan: 1, colspan: 1 },
          wednesday: { name: 'CSS', rowspan: 1, colspan: 1 },
          thursday: { name: 'REACT', rowspan: 1, colspan: 1 },
          friday: { name: '语文', rowspan: 1, colspan: 1 },
          saturday: { name: 'CSS', rowspan: 1, colspan: 1 },
          sunday: { name: 'JS', rowspan: 1, colspan: 1 },
        },
        {
          classesTime: '15:00-16:00',
          monday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          tuesday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          wednesday: { name: '语文', rowspan: 1, colspan: 1 },
          thursday: { name: 'JQUERY', rowspan: 1, colspan: 1 },
          friday: { name: 'DATA', rowspan: 1, colspan: 1 },
          saturday: { name: 'JS', rowspan: 1, colspan: 1 },
          sunday: { name: '', rowspan: 1, colspan: 1 },
        },
      ],
      tableShow: false,
    }
  },
  created() {
    // /* mock随机数据*/
    //  Mock.mock({
    //     'data|7': [
    //         {
    //             'classesTime|+1': ['08:00-09:00', '09:00-10:00', '10:00-11:00', '11:00-12:00', '13:00-14:00', '14:00-15:00', '15:00-16:00', '16:00-17:00'],
    //             'monday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'tuesday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'wednesday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'thursday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'friday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'saturday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文'],
    //             'sunday|1': ['DATA', 'CSS', 'REACT', 'VUE', 'JQUERY', 'JS', '', '语文']
    //         }
    //     ]
    // });
  },
  methods: {
    /**
     * 数字转中文
     * @param {Number} num 需要转换的数字
     * @param {String} identifier 标识符
     * @returns {String} 转换后的中文
     */
    digital2Chinese(num, identifier) {
      const character = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
      return identifier === 'week' && (num === 0 || num === 7) ? '日' : character[num]
    },
  },
}
</script>

<style lang="less" scoped>
.class-table {
  .table-wrapper {
    width: 100%;
    height: 100%;
    overflow: auto;
  }
  .tabel-container {
    margin: 7px;

    table {
      table-layout: fixed;
      width: 100%;

      thead {
        background-color: #67a1ff;
        th {
          color: #fff;
          line-height: 17px;
          font-weight: normal;
        }
      }
      tbody {
        background-color: #eaf2ff;
        td {
          color: #677998;
          line-height: 12px;
        }
      }
      th,
      td {
        width: 60px;
        padding: 12px 2px;
        font-size: 12px;
        text-align: center;
        border: 1px solid grey;
      }

      tr td:first-child {
        color: #333;
        .period {
          font-size: 8px;
        }
      }
    }
  }
}
</style>

备注:表格数据参考这位博主:vue实现table课程表

;