工作中经常会遇到横向表格实现横向、纵向滚动。要实现这样效果通常我们会根据业务情况使用双table或者多个div拼接来实现。
布局
就拿上图来说,他的场景是左侧显示名称,右侧3列根据业务需求展示不同的数据与逻辑,由4个div拼接而成,要实现这样的效果且实现滚动,则采用的布局为左右布局+滚动联动。左侧名称为一个单独div,右侧数据为一个div。右侧的div内部由3个div组成。如下图所示:
<div class="main">
<div class="table-header" id="tableHeader">
<div v-for="item in 100" class="header-cell">{{ item }}</div>
</div>
<div class="table-body">
<div class="table-rows">
<div v-for="item in 100" class="body-cell">{{ item }}</div>
</div>
<div class="table-rows">
<div v-for="item in 100" class="body-cell">{{ item }}</div>
</div>
<div class="table-rows">
<div v-for="item in 100" class="body-cell">{{ item }}</div>
</div>
</div>
</div>
样式实现
.main{
width: 100%;
height: 100%;
background: white;
width: 100%;
height: calc(100% - 36px);
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.table-header {
overflow: hidden;
position: sticky;
top: 0;
z-index: 10;
width: 80px;
height: 100%;
display: flex;
flex-direction: column;
background-color: #f5f7fa;
border-bottom: 1px solid #ebeef5;
}
.table-body {
overflow-y: auto;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
flex-wrap: wrap;
.table-rows {
display: flex;
width: 40%;
position: relative;
flex-direction: column;
flex-wrap: wrap;
}
}
.header-cell,
.body-cell {
padding: 12px 0;
display: flex;
justify-content: center;
align-items: center;
border: 0.25px solid #c9c9c9;
}
/*设置纵向滚动样式*/
.header-cell:first-of-type , .body-cell:first-of-type {
position: sticky;
z-index: 1;
top: 0;
background: white;
}
.table-rows{
width: 400px;
}
设置完样式后仅仅能实现横向滚动,但是纵向滚动并不能联动,还需要js加持
import {
onMounted
} from 'vue';
let tableHeaderDom, tableBodyDom = null
onMounted(() => {
tableHeaderDom = document.querySelector('.table-header')
tableBodyDom = document.querySelector('.table-body')
tableHeaderDom && tableHeaderDom.addEventListener('scroll',scrollTableHead)
tableBodyDom && tableBodyDom.addEventListener('scroll',scrollTableBody)
})
const scrollTableHead = () => {
if (tableHeaderDom && tableBodyDom) {
tableBodyDom.scrollTop = tableHeaderDom.scrollTop
}
}
const scrollTableBody = () => {
if (tableHeaderDom && tableBodyDom) {
tableHeaderDom.scrollTop = tableBodyDom.scrollTop
}
}
最后在钩子函数中自行增加离开页面销毁监听
tableHeaderDom && tableHeaderDom.removeEventListener('scroll',this.scrollTableHead)
tableBodyDom && tableBodyDom.removeEventListener('scroll',this.scrollTableBody)
效果
设置完成之后就可以看到横向、纵向的滚动效果了