绘制 Vue.js 数据驱动的纵向表格

效果图

绘制 Vue.js 数据驱动的纵向表格

设计思想

       我的想法是,纵向表格不固定显示几行几列,怎么显示都由数据决定。如上图,前面 6 行因为内容比较短,可以放置 2 大列(4 小列),后面 3 行的内容可能会比较长,最好不要再分成 2 大列,一行就能显示完自然是极好的。那么就把表格看成一个二维数组 array,第一维是行 row,第二维是大列 col,每个大列中的数据是一组 KV 键值对。假设我 row,push 了 3 个 col 进去,就表示有三个大列,再用 array 把 row 给 push 进去,这样一行就完成了。如果只需要一个大列,那么 row 只要 push 一个 col 就行了。

数据驱动

handleTeacherData (teacher) {
    if (!teacher) {
        return
    }
    let table = [] // 大表格
    let tmpRow = [] // 临时数组,表示 row,一行数据

    tmpRow.push({key: '姓名', value: teacher.username})
    tmpRow.push({key: '性别', value: this.formatGender(teacher.gender)})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '国籍', value: teacher.nativeLocation.countryName)})
    tmpRow.push({key: '民族', value: teacher.nation})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '工作单位', value: teacher.orgName})
    tmpRow.push({key: '部门', value: ''})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '毕业院校', value: teacher.graduatedSchool})
    tmpRow.push({key: '专业', value: teacher.graduatedMajor})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '工作地址', value: this.formatLocation(teacher.user.location)})
    tmpRow.push({key: '故乡', value: this.formatLocation(teacher.user.nativeLocation)})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '研究方向', value: teacher.researchArea})
    tmpRow.push({key: '分类', value: teacher.classificationCodeName})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '代表作品', value: teacher.representativeAchievements})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '主要成就', value: teacher.mainAchievements})
    table.push(tmpRow)
    tmpRow = []

    tmpRow.push({key: '在线课程', value: this.courseList.map(item => item.name).join('、')})
    table.push(tmpRow)
    tmpRow = []

    this.dataArray = table
}

HTML 代码

<template>
  <div class="table-box">
    <table class="table-body">
      <tr class="tr-body" v-for="(row, outerIndex) in dataArray" :key="outerIndex">
        <!-- flex: 0 0 x% 自适应布局,每一大列的宽度按百分比显示 -->
        <div class="td-box" :style="{flex: '0 0 ' + 100 / row.length + '%'}" v-for="(col, innerIndex) in row" :key="innerIndex">
          <td class="td-key">{{ col.key }}</td>
          <td class="td-value">{{ col.value }}</td>
        </div>
      </tr>
    </table>
  </div>
</template>

JavaScript 代码

<script>
  export default {
    props: {
      dataArray: {
        type: Array,
        require: true
      }
    }
  }
</script>

SCSS 代码

<style lang="scss" scoped>
  .table-box {

    .table-body {
      width: 100%;
      border: 1px solid $line-color;

      .tr-body {
        display: flex;
        border-bottom: 1px solid $line-color;

        &:last-child {
          border-bottom: 0;
        }

        .td-box {
          display: flex;
          border-left: 1px solid $line-color;

          &:first-child {
            border-left: 0;
          }

          .td-key {
            width: 120px;
            padding: 10px;
            line-height: 20px;
            text-align: center;
            background-color: $grey-bg;
            border-right: 1px solid $line-color;
          }

          .td-value {
            flex: 1 0;
            line-height: 20px;
            padding: 10px 20px;
          }
        }
      }
    }
  }
</style>