vue表格实现固定表头首列
2018.12.24
小林同學
前端
 热度
℃
前言
最近在做vue移动端项目,需要做一个可以固定表头首列的表格,而且由于一些原因不能使用任何UI插件,网上找了很久也没什么好方法,所以在解决了问题之后,写下了这篇文章供后来人参考,文章有什么错漏的问题欢迎评论交流。
效果

思路
要实现固定首行首列
除了使用各种UI框架插件外,那就是自己用原生写啦
首先我们理一下思路
如何固定首行首列呢?
可能每个人有不同的想法
我这里当然介绍的是我自己的想法
那就是把首列表头和表格主内容分割开来,如下图
不过这样虽然固定了表头首列
但还是不能实现我们想要的效果
因为你会发现当你滑动tbody的时候
表头和首列并不会移动
相信聪明的你已经有了解决的办法了
那就是给tbody添加一个滑动监听
滑动的时候会触发事件
引起表头和首列的移动
这就是本文固定表头首列的思路

代码实现
template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| <template> <div class="pages" ref="pages"> <div class = "content" ref="table"> <div class = "left-content"> <div class = "table-head"> <table class= "full-table"> <thead> <tr v-for = "header in tableHeader"> <th class = "firstCol" v-for = "(b,index) in header" v-if="index==0"> <p>{{b}}</p> </th> </tr> </thead> </table> </div> <div class="table-left"> <div class = "table" ref="firstColLayer" data-_ref="firstColLayer" > <table class= "full-table"> <tbody> <tr v-for="row in dataSheet"> <td v-for="(c,index) in row" v-if="index==0"> <p>{{c}}</p> </td> </tr> </tbody> </table> </div> </div> </div> <div class = "right-content" ref="right"> <div class = "table-head" ref="firstRowLayer" data-_ref="firstRowLayer"> <table class= "full-table"> <thead> <tr v-for = "header in tableHeader"> <th v-for = "(b,index) in header" v-if="index!=0 && index!=1" style="width:101px" > <p>{{b}}</p> </th> </tr> </thead> </table> </div> <div class="table" style="overflow:scroll" ref="tableContainer" @scroll="tableDivScroll($event)" > <table class="content-table"> <tbody ref="tbody"> <tr v-for="row in dataSheet"> <td v-for="(c,index) in row" v-if="index!=0 && index!=1" > <p>{{c}}</p> </td> </tr> </tbody> </table> </div> </div> </div> </div> </template>
|
JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <script> module.exports = (function(that) { return { data: function(that) { const tableHeader = that.dataSheet; const dataSheet = that.dataSheet; return { dataSheet: dataSheet, tableHeader: tableHeader, }; }, methods: { tableDivScroll (event) { const $target = this.$refs.tableContainer this.$refs.firstRowLayer.scrollLeft = $target.scrollLeft this.$refs.firstColLayer.scrollTop = $target.scrollTop }, mounted:function () { let maxHeight = window.screen.height document.body.style.overflow='hidden'; this.$refs.right.style.width=""+this.$refs.table.offsetWidth-107+"px"; console.log(this.placeholderTop) } } })(this); </script>
|
CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <style scoped> body{ overflow:hidden } .pages{ height:100%; overflow:hidden; } .content{ margin-top:73px; margin-left:17px; width:100%; } .left-content{ width:101px; float:left; } .right-content{ float:left } .table-body{ width:100%; overflow:auto; } .table-head{ width:100%; overflow:hidden; } .left-content .table-body{ overflow:hidden; } .table-left .table{ height:400px; background-color:#FFFFFF; overflow:hidden; margin-right:0; padding-right:0; } table::-webkit-scrollbar{display:none} .content-table th, .full-table th{ font-size:14px; font-family:PingFangSC-Regular; background:#EAEFF3; font-weight:400; color:#176BED; height:40px; line-height:40px; text-align:center; } .content-table td, .full-table td { line-height: 35px; text-align: center; word-wrap: break-word; word-wrap: normal\0; overflow: hidden; -o-text-overflow: ellipsis; text-overflow: ellipsis; } th,td p{ width:101px; display: inline-block; line-height:14px; padding:auto 0; margin:auto 0; vertical-align: middle; } .content-table { display:block; background-color:#FFFFFF; } thead,tbody{ background-color:#FFFFFF; } </style>
|
Ps:有什么问题可以在评论区一起探讨