由于移动端项目需求要实现一个能够固定表格首列和表头的表格,可是移动端对表格需求不多,用的组件库中也没有设计这个组件,也不能用插件,因此只能本身写一个。语言是vue。css
基本思想:把首列和表头和主体表格分开;而后给tbody添加一个滑动监听,滑动的时候,触发事件让表头和首列固定就能够。html
可是注意的是,高度和宽度必须都要统一设置好,否则会出现表格不对齐的问题。vue
实现效果:
web
代码实现:(vue主体部分)svg
<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样式:this
<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.htmlspa