移动端实现固定表格首列和表头(vue)
因为移动端项目需求要实现一个可以固定表格首列和表头的表格,但是移动端对表格需求很少,用的组件库中也没有设计这个组件,也不能用插件,所以只能自己写一个。语言是vue。
基本思想:把首列和表头和主体表格分开;然后给tbody添加一个滑动监听,滑动的时候,触发事件让表头和首列固定就可以。
但是注意的是,高度和宽度必须都要统一设置好,不然会出现表格不对齐的问题。
实现效果:
代码实现:(vue主体部分)
<template>
<div
ref="pages"
class="pages"
>
<div
ref="table"
class="content1"
>
<!--首列固定-->
<div class="left-content">
<div class="table-head">
<table class="full-table">
<thead>
<tr
v-for="(header,index) in tableHeader"
:key="index"
>
<th
v-for="(b,x) in header"
v-show="x===0"
:key="x"
>
<p>
{{ b }}
</p>
</th>
</tr>
</thead>
</table>
</div>
<div class="table-left">
<div
ref="firstColLayer"
class="table"
data-_ref="firstColLayer"
>
<table class="full-table">
<tbody>
<tr
v-for="(row,index) in dataSheet"
:key="index"
>
<td
v-for="(c,y) in row"
v-show="y===0"
:key="y"
>
<p>{{ c }}</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div
ref="right"
class="right-content"
>
<!--首行固定-->
<div
ref="firstRowLayer"
class="table-head"
data-_ref="firstRowLayer"
>
<table>
<thead>
<tr
v-for="(header,index) in tableHeader"
:key="index"
>
<th
v-for="(b,n) in header"
v-show="n!==0"
:key="n"
>
<p>
{{ b }}
</p>
</th>
</tr>
</thead>
</table>
</div>
<!--正常表格内容(只有表格内容,没有表头和首列)-->
<div
ref="tableContainer"
class="table"
style="overflow:scroll"
@scroll="tableDivScroll($event)"
>
<table>
<tbody ref="tbody">
<tr
v-for="(row,index) in dataSheet"
:key="index"
>
<td
v-for="(c,m) in row"
v-show="m!==0"
:key="m"
>
<p>{{ c }}</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Table",
data() {
return {
dataSheet: [
[
"承订人", "2222222", "123", "444444", "20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "圣", "444444","20%", "20%",
],
[
"111", "2222222", "圣卡夫2", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "3333333", "444444","20%", "20%",
],
[
"111", "2222222", "333", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
[
"111", "2222222", "123", "444444","20%", "20%",
],
],
tableHeader: [
[
"人员代码","派工件数","预算金额","实际金额","当月达成率","全年达成率",
],
],
};
},
mounted() {
// 定一个生命周期钩子监听变动
// let maxHeight = window.screen.height
document.body.style.overflow = "hidden";
// this.$refs.right.style.width =
// "" + this.$refs.table.offsetWidth - 12 + "px"; // 这里的减101是减去左侧div宽度
// console.log(this.$refs.right.style.width);
},
activated: function() {},
methods: {
tableDivScroll() {
const $target = this.$refs.tableContainer;
// 首行固定
this.$refs.firstRowLayer.scrollLeft = $target.scrollLeft;
// 首列固定
this.$refs.firstColLayer.scrollTop = $target.scrollTop;
},
},
};
</script>
css样式:
<style scoped>
/* 表格分为两部分,左边固定列和右边表格
左边固定列宽度为60px;右边为70px,右边因为要加边框 所以就是68+2px(左右边框) */
body {
overflow: hidden;
}
table::-webkit-scrollbar {
display: none;
}
thead,
tbody {
overflow: hidden;
background-color: #ffffff;
}
th,
td p {
width: 68px;
height: 40px;
display: inline-block;
line-height: 20px;
padding: auto 0;
margin: auto 0;
vertical-align: middle;
white-space:normal;
}
tr {
height: 40px;
}
th {
background-color: #cbcdc8;
}
td{
border: 1px solid
}
.pages {
height: 100%;
overflow: hidden;
}
.content1 {
height: 450px;
overflow: hidden;
margin: 5px;
}
/* 固定列的宽度为60 */
.left-content {
width: 60px;
float: left;
text-align: center;
border-top: 1px solid
}
.left-content p{
width: 60px;
height: 40px;
word-wrap: break-word;
}
.right-content{
border-top: 1px solid
}
/* 去掉表格的重复边框 */
.full-table{
border: 0px;
border-collapse: collapse;
}
.table-body {
width: 100%;
overflow: auto;
}
.table {
height: 450px;
overflow: auto;
}
/* 表头 */
.table-head {
overflow: hidden;
white-space: nowrap;
}
.table-head th{
width: 69px;
border-left: 1px solid;
}
</style>
说明:功能是实现了,代码里面也有注释,但是兼容性做的还不是很好,希望大佬们给出建议和帮助。
参考文章:https://www.cnblogs.com/linwene/p/10169545.html