绘制 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>