1、演示
2、思路
1、用传统的 <table></table> 表格标签来实现比较麻烦。因此通过模拟 表格标签 的写法用**<div></div>**来实现
2、表头和表格列数是相同的,因此可以确定代码结构
html<div class="table"> <div class="header"> <div class="th"></div> <div class="th"></div> <div class="th"></div> <div class="th"></div> <div class="th"></div> </div> <div class="body"> <div class="tr"> <div class="td"></div> <div class="td"></div> <div class="td"></div> <div class="td"></div> <div class="td"></div> </div> </div> </div>
3、上述代码表示为一个一行五列的表格
4、通过flex进行布局
5、通过数组的长度来平分嵌套表格每一列的宽度/高度
3、全部代码
html
<template>
<div class="table">
<div class="header">
<div class="th">Id</div>
<div class="th">名字</div>
<div class="th">年龄</div>
<div class="th">朋友</div>
<div class="th">性别</div>
</div>
<div class="body">
<div class="tr" v-for="(item, index) in data">
<div class="td">{{ item.id }}</div>
<div class="td">{{ item.name }}</div>
<div class="td">{{ item.age }}</div>
<div class="td" style="flex-direction: column">
<p @click="item.hide = !item.hide">展开详情</p>
<div
class="content"
:style="{ height: item.hide ? '0px' : `${item.detail.length * 36}px` }"
:class="item.hide ? '' : 'haveTopBorder'"
:key="index"
>
<div class="content-row" v-for="item1 in item.detail">
<div class="content-td" v-for="item2 in item1" :style="{ '--l': item1.length }">{{ item2 }}</div>
</div>
</div>
</div>
<div class="td">是</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
const data = ref([
{
id: 1,
name: '刘备',
age: '18',
detail: [
['1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111'],
],
status: '男',
hide: false,
},
{
id: 2,
name: '张飞',
age: '50',
detail: [
['1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '', '1111'],
['1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111', '1111'],
],
status: '男',
hide: false,
},
{
id: 3,
name: '关羽',
age: '29',
detail: [
['', '1111', '1111', '1111', '1111', '1111', '', '1111', '1111', '', '1111'],
['1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111', '1111', ''],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
['1111', '', '1111', '1111', '', '1111', '1111', '1111', '1111', '1111', '1111'],
],
status: '男',
hide: false,
},
])
</script>
<style scoped lang="scss">
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.table {
width: 1000px;
border: 1px solid #eee;
font-size: 14px;
.header {
display: flex;
justify-content: space-between;
align-items: stretch;
background-color: #b6bece;
color: #3c3c3c;
padding: 8px 0;
.th {
padding-left: 8px;
}
}
.body {
width: 100%;
.tr {
display: flex;
width: 100%;
justify-content: space-between;
align-items: stretch;
border-bottom: 1px solid #eee;
.td {
border-right: 1px solid #eee;
padding: 8px 4px;
display: flex;
justify-content: flex-start;
align-items: center;
}
.td:last-child {
border-right: 0;
}
}
.tr:last-child {
border-bottom: 0;
}
p {
width: 100%;
display: flex;
align-items: center;
text-align: left;
padding: 8px 0;
cursor: pointer;
user-select: none;
}
}
.th,
.td {
text-align: left;
}
.th:nth-child(1),
.td:nth-child(1) {
width: 70px;
}
.th:nth-child(2),
.td:nth-child(2) {
width: 100px;
}
.th:nth-child(3),
.td:nth-child(3) {
width: 130px;
}
.th:nth-child(4),
.td:nth-child(4) {
flex: 1;
padding: 0 !important;
}
.th:nth-child(5),
.td:nth-child(5) {
width: 70px;
}
.content {
width: 100%;
overflow: hidden;
transition: height 0.2s;
.content-row {
display: flex;
width: 100%;
border-bottom: 1px solid #eee;
.content-td {
padding: 8px;
width: calc(100% / var(--l));
border-right: 1px solid #eee;
}
.content-td:last-child {
border-right: 0;
}
}
.content-row:last-child {
border-bottom: 0;
}
.content-row:nth-child(even) {
background-color: rgb(116, 182, 218);
}
}
.haveTopBorder {
border-top: 1px solid #eee;
}
}
</style>
4、温馨提示
您可以找个干净的页面直接整个复制,根据您的需求更改即可