欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue表格实现固定表头首列

程序员文章站 2023-02-20 21:32:35
前言 最近在做vue移动端项目,需要做一个可以固定表头首列的表格,而且由于一些原因不能使用任何UI插件,网上找了很久也没什么好方法,所以在解决了问题之后,写下了这篇文章供后来人参考,文章有什么错漏的问题欢迎评论交流。 效果 思路 要实现固定首行首列 除了使用各种UI框架插件外,那就是自己用原生写啦 ......

前言

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

效果

vue表格实现固定表头首列

思路

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

代码实现

<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:有什么问题可以在评论区一起探讨