vue+html實現固定表頭及固定列(固定複製表頭和指定列可以根據同樣思想設置)

vue固定表頭和列

這篇文章基於原生html+vue實現表頭固定和列固定,如果是使用瞭如element-ui等一般已經有相應實現組件。

1.基本思想

通過使用css中的transform(可以平移或旋轉等),結合對scroll滾動條的監聽實現固定表頭和列。首先監聽scroll滾動,獲取其向上或向下滾動的距離,然後通過transform將表頭上下平移,或者將制定列左右平移相應距離即可。

步驟

1.創建一個表格,指定表格高度和寬度,外層嵌套一個div盒子
2.給表格寫cssh(這裏通過制定class來寫css,class名稱會在指令中用到)
3.使用directives創建一個自定義指令(具體功能見代碼)

注:這裏有個問題沒有解決,即同時固定列和表頭,上下拖動滾動條時固定列會遮蓋相應列的表頭,目測是由於設置背景色導致的,後面再弄。

代碼
<template>
    <div class="app">
        <div class="wrapper" v-fixed-thead>
            <table>
                <thead>
                    <tr>
                        <th v-for="index in 14" style="width: 100px;" :class="index == 1 ? 'th_blue' : 'th_red'">標題{{index}}</th>
                    </tr>
                </thead>
                <thead>
                    <tr>
                        <th v-for="index in 14" style="width: 100px;" :class="index == 1 ? 'th_blue' : 'th_red'">標題{{index}}</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="index1 in 20">
                        <td v-for="index in 14" style="width: 100px;" :class="index == 1 ? 'td_blue' : 'td_yellow'">{{index1}}行{{index}}列哈哈哈哈哈哈哈哈</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</template>
<script>

    export default {
        directives: {
            'fixed-thead': {
                bind: function(el) {
                    el.onscroll=function(){
                        // 獲取上下,左右滾動距離
                        let scrollTop=el.scrollTop;
                        let scrollLeft = el.scrollLeft;

                        // 獲取組件
                        let theadList = el.querySelectorAll('thead');
                        let thLeftList = document.getElementsByClassName('th_blue');
                        let tdLeftList = document.getElementsByClassName('td_blue');

                        // 固定表頭
                        if(theadList) {
                            for(let i=0; i<theadList.length; i++) {
                                theadList[i].style.transform='translateY('+scrollTop+'px)';
                            }
                        }
                        // 固定表格中含有類名爲td_blue的元素
                        if(tdLeftList) {
                            for(let i=0; i<tdLeftList.length; i++) {
                                tdLeftList[i].style.transform = 'translateX('+scrollLeft+'px)';
                            }
                        }
                        // 固定表頭中含有類名爲th_blue的元素
                        if(thLeftList) {
                            for(let i=0; i<thLeftList.length; i++) {
                                thLeftList[i].style.transform = 'translateX('+scrollLeft+'px)';
                            }
                        }
                    };
                }
            }
        },
    }

</script>
<style lang="scss" scoped>

    .app {
        .wrapper {
            height: 400px;
            overflow: auto;

            table {
                border-collapse: collapse;
                border: 1px solid grey;

                tr {
                    height: 10px;
                    /*background-color: #ffffff;*/

                    .th_blue {
                        background-color: blue;
                        z-index: 2;
                    }

                    .th_red {
                        background-color: red;
                        z-index: 2;
                    }

                    .td_blue {
                        background-color: #ffffff;
                        border: 1px solid grey;
                        white-space: nowrap;
                    }

                    .td_yellow {
                        background-color: yellow;
                        border: 1px solid grey;
                        white-space: nowrap;
                    }
                }
            };
        }

    }
</style>

不出意外將上面的代碼直接複製到你的項目中就可以查看到效果,如圖:
在這裏插入圖片描述
這裏是把固定頭和固定列寫在了一起,如果單獨需要可以屏蔽掉directives中的代碼。這裏也設置了兩個thead,目的是如果需要使用複雜表頭可以這樣弄,當然也可以給複雜表頭指定class或者id,在directives中通過class名稱或id名稱去獲取來設置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章