vue表格實現固定表頭首列


前言

最近在做vue移動端項目,需要做一個可以固定表頭首列的表格,而且由於一些原因不能使用任何UI插件,網上找了很久也沒什么好方法,所以在解決了問題之后,寫下了這篇文章供后來人參考,文章有什么錯漏的問題歡迎評論交流。

效果

思路

要實現固定首行首列
除了使用各種UI框架插件外,那就是自己用原生寫啦
首先我們理一下思路
如何固定首行首列呢?
可能每個人有不同的想法
我這里當然介紹的是我自己的想法
那就是把首列表頭和表格主內容分割開來,如下圖
不過這樣雖然固定了表頭首列
但還是不能實現我們想要的效果
因為你會發現當你滑動tbody的時候
表頭和首列並不會移動
相信聰明的你已經有了解決的辦法了
那就是給tbody添加一個滑動監聽
滑動的時候會觸發事件
引起表頭和首列的移動
這就是本文固定表頭首列的思路

代碼實現

template:

<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:

<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";//這里的減107是減去左側div寬度
              	console.log(this.placeholderTop)
            }
        }
    })(this);
</script>

CSS:

<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:有什么問題可以在評論區一起探討


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM