vue表格實現固定表頭首列
阿新 • • 發佈:2018-12-24
前言
最近在做vue移動端專案,需要做一個可以固定表頭首列的表格,而且由於一些原因不能使用任何UI外掛,網上找了很久也沒什麼好方法,所以在解決了問題之後,寫下了這篇文章供後來人參考,文章有什麼錯漏的問題歡迎評論交流。
效果
思路
要實現固定首行首列
除了使用各種UI框架外掛外,那就是自己用原生寫啦
首先我們理一下思路
如何固定首行首列呢?
可能每個人有不同的想法
我這裡當然介紹的是我自己的想法
那就是把首列表頭和表格主內容分割開來,如下圖
不過這樣雖然固定了表頭首列
但還是不能實現我們想要的效果
因為你會發現當你滑動tbody的時候
表頭和首列並不會移動
相信聰明的你已經有了解決的辦法了
那就是給tbody新增一個滑動監聽
滑動的時候會觸發事件
引起表頭和首列的移動
這就是本文固定表頭首列的思路
程式碼實現
<template> <div class="pages" ref="pages"> <div class = "content" ref="table"> <!--首列固定(就是隻有首列資料)--> <div class = "left-content"> <div class="table-left" ref="firstColLayer" data-_ref="firstColLayer"> <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> <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 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" 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" > <p>{{c}}</p> </td> </tr> </tbody> </table> </div> </div> <!--第一格固定--> <div class="table-fixed-layer"> <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> </div> </template> <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"; }, computed: { } } })(this); </script> <style scoped> body{overflow:hidden} .pages{ height:100%; overflow:hidden; } .head{ position:absolute; top:0; left:0; height:73px; padding:16px; width:100%; z-index:99; background:#fff } .right-head{ position:absolute; top:16px; right:12px; } .right-head .subsidiary{ height:17px; margin:0; padding:0; font-size:12px; font-family:PingFangSC-Regular; font-weight:400; color:#A4A8AB; line-height:17px; } .head .title { height:18px; font-size:16px; font-family:PingFangSC-Medium; font-weight:500; color:#1D1D1D; line-height:18px; padding-bottom:0; margin-bottom:0; } .head .deadline{ margin-top:6px; height:17px; font-size:12px; font-family:PingFangSC-Regular; font-weight:400; color:#A4A8AB; line-height:17px; } .content{ margin-top:73px; margin-left:17px; width:100%; } .left-content{ width:101px; float:left; } .right-content{ float:left } .table-body{ width:100%; height:220px; overflow:auto; } .table-head{ width:100%; overflow:hidden; } .left-content .table-body{ overflow:hidden; } .table-left{ height:440px;/*400表格高度加上40表頭高度*/ background-color:#FFFFFF; overflow:hidden; margin-right:0; padding-right:0;} .table{ height:400px;/*表格高低(要修改高度修改這個和table-left註釋的那個)*/ background-color:#FFFFFF; overflow:hidden; margin-right:0; padding-right:0; } .table::-webkit-scrollbar{display:none} /*第一格固定css*/ .table-fixed-layer{ position: fixed; overflow:hidden; left:17px; top:73px; z-index:99; } .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 p{ width:101px; display: inline-block; line-height:14px; padding:auto 0; margin:auto 0; vertical-align: middle; } td p{ width:101px; display: inline-block; line-height:14px; padding:auto 0; margin:auto 0; vertical-align: middle; } .content-table { display:block; /*table-layout: fixed;*/ background-color:#FFFFFF; } </style>
Ps:有什麼問題可以在評論區一起探討