通用表格:可折叠,可合并,多列折行显示,自定义固定头,自定义固定列,移动端,vue

一 基本用法:

js模板:

 <script>
        var genbody = `
            <table>
             <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                 <tbody v-for="(data,index) in tableData">
                 <tr>
                     <td>
                         {{index+1}}
                     </td>
                     <td>
                         {{data.RealName}}
                     </td>
                     <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                 </tr>
                 </tbody>
              </table>
`
        var genhead = `
         <table>
                <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                <tbody>
                <tr>
                    <td >
                        序号
                    </td>
                    <td>
                        姓名
                    </td>
                    <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                    <td>
                        状态
                    </td>
                </tr>
                </tbody>
            </table>

        `;
    </script>

css样式:

 <style>
        table{
            width:385px;
        }
        tr {
            height:40px;
        }

        td {
            border: 1px solid #ebeef5;
            word-break: break-all;
            text-align: center;
            padding: 0px;
            vertical-align: middle;
        }
</style>

html组件:

<body>
            <my-head>
                <gen-head ></gen-head>
            </my-head>
            <my-body>
                <gen-body :table-data="UserArr" ></gen-body>
            </my-body>
</body>

js函数:

效果:

五列数据,不可折叠,不可左右滑动,无固定行,无固定列,就是一个基本表格,想要什么样式在js模板或者写css

 二:单行合并单元格

js模板:

 <script>
        var genbody = `
            <table>
             <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                 <tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}">
                 <tr>
                     <td colspan="2">
                         {{index+1}}
                     </td>
                     <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                 </tr>
                 </tbody>
              </table>
`
        var genhead = `
         <table>
                <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                <tbody>
                <tr>
                    <td colspan="2">
                        序号
                    </td>
                    <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                    <td>
                        状态
                    </td>
                </tr>
                </tbody>
            </table>

        `;
    </script>

css样式:

 <style>
        table{
            width:385px;
        }
        tr {
            height:40px;
        }

        td {
            border: 1px solid #ebeef5;
            word-break: break-all;
            text-align: center;
            padding: 0px;
            vertical-align: middle;
        }

        .on {
            background: #F5F7FA;
        }

        .off {
            background: white;
        }
</style>

其他不变.

效果:

:

 三:多行,合并,隔行换色

js模板:

<script>
        var genbody = `
            <table>
             <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                 <tbody v-for="(data,index) in tableData">
                 <tr>
                     <td rowspan="2">
                         {{index+1}}
                     </td>

                     <td colspan="2">
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.RealName}}
                     </td>
                 </tr>
                 <tr>
                     <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                 </tr>
                 </tbody>
              </table>
`
        var genhead = `
         <table>
                <colgroup>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                    <col width="20%"></col>
                </colgroup>
                <tbody>
                <tr>
                    <td rowspan="2">
                        序号
                    </td>
                    <td colspan="2">
                        用户名
                    </td>
                    <td >
                        姓名
                    </td>
                </tr>
                 <tr>
                    <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                     <td >
                        状态
                    </td>
                </tr>
                </tbody>
            </table>

        `;
    </script>

其他不变:

效果:

四:三的基础上加上可展开折叠效果

js模板:

 <script>
        var genbody = `
            <table>
             <colgroup>
                    <col width="25%"></col>
                    <col width="25%"></col>
                    <col width="25%"></col>
                    <col width="25%"></col>
                </colgroup>
                 <tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}" @click="$emit('bodys',index)">
                 <tr>
                     <td rowspan="2">
                         {{index+1}}
                     </td>

                     <td colspan="2">
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.RealName}}
                     </td>
                 </tr>
                 <tr v-show="store.Current == index">
                     <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                 </tr>
                 </tbody>
              </table>
`
        var genhead = `
         <table>
                <colgroup>
                    <col width="25%"></col>
                    <col width="25%"></col>
                    <col width="25%"></col>
                    <col width="25%"></col>
                </colgroup>
                <tbody @click="$emit('heads')">
                <tr>
                    <td rowspan="2">
                        序号
                    </td>
                    <td colspan="2">
                        用户名
                    </td>
                    <td >
                        姓名
                    </td>
                </tr>
                 <tr v-show="head">
                    <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                     <td >
                        状态
                    </td>
                </tr>
                </tbody>
            </table>

        `;
    </script>

css样式:不变

html组件:

           <my-head>
                <gen-head @heads="heads" :head="head" ></gen-head>
            </my-head>
            <my-body>
                <gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
            </my-body>

vue中的store(即vue中的data属性):

 var store = {
        Current: null,
        body: false,
        head: false,
...
}

vue中的methods(自定义点击事件的方法):

 methods: {

            bodys: function (index) {
                if (store.Current == index) {
                    store.Current = null;
                } else {
                    store.Current = index;
                }
            },
            heads: function () {
                if (store.head == true) {
                    store.head = false;
                } else {
                    store.head = true;
                }
            },
...
}

效果:

 五:四的基础上可左右滚定,

js模板:

 <script>
        var genbody = `
            <table>
             <colgroup>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                </colgroup>
                 <tbody v-for="(data,index) in tableData" :class="{on:index%2==0,off:index%2!=0}" @click="$emit('bodys',index)">
                 <tr>
                     <td rowspan="2">
                         {{index+1}}
                     </td>

                     <td colspan="2">
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.RealName}}
                     </td>
                      <td rowspan="2">
                         {{index+1}}
                     </td>

                     <td colspan="2">
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.RealName}}
                     </td>
                 </tr>
                 <tr v-show="store.Current == index">
                     <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                       <td>
                         {{data.Username}}
                     </td>
                     <td>
                         {{data.UnitName}}
                     </td>
                     <td>
                         {{data.StateStr}}
                     </td>
                 </tr>
                 </tbody>
              </table>
`
        var genhead = `
         <table>
                <colgroup>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                    <col width="12.5%"></col>
                </colgroup>
                <tbody @click="$emit('heads')">
                <tr>
                    <td rowspan="2">
                        序号
                    </td>
                    <td colspan="2">
                        用户名
                    </td>
                    <td >
                        姓名
                    </td>
                        <td rowspan="2">
                        序号
                    </td>
                    <td colspan="2">
                        用户名
                    </td>
                    <td >
                        姓名
                    </td>
                </tr>
                 <tr v-show="head">
                    <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                     <td >
                        状态
                    </td>
                      <td>
                        用户名
                    </td>
                    <td>
                        部门名称
                    </td>
                     <td >
                        状态
                    </td>
                </tr>
                </tbody>
            </table>

        `;
    </script>

css样式:

<style>
        table{
            width:750px;
        }
        .body {
            width:375px;
            overflow: scroll;
        }
        .header {
            width:375px;
            overflow: scroll;
        }
        tr {
            height:40px;
        }

        td {
            border: 1px solid #ebeef5;
            word-break: break-all;
            text-align: center;
            padding: 0px;
            vertical-align: middle;
        }

        .on {
            background: #F5F7FA;
        }

        .off {
            background: white;
        }
</style>

html组件:上一个的基础上不变

js(vue data不变):

js(vue methods不变):

vue之后加一个jquery函数(用于表头表体联动):

$(function () {
        $('.body').on('scroll', function () {
            let left = $(this).scrollLeft();
            $('.header').scrollLeft(left);
        });
    });

效果:

 

六:固定第一列:

js模板:跟之前的一样

html组件:

           <my-fix>
                <template slot="fixhead">
                    <gen-head @heads="heads" :head="head"></gen-head>
                </template>
                <gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
            </my-fix>
            <my-head>
                <gen-head @heads="heads" :head="head" ></gen-head>
            </my-head>
            <my-body>
                <gen-body :table-data="UserArr" @bodys="bodys"></gen-body>
            </my-body>

css样式:

<style>
        table{
            width:750px;
        }
        .body {
            width:375px;
            overflow: scroll;
        }
        .header {
            width:375px;
            overflow: scroll;
        }
        tr {
            height:40px;
        }

        td {
            border: 1px solid #ebeef5;
            word-break: break-all;
            text-align: center;
            padding: 0px;
            vertical-align: middle;
        }
        /*用于阻止用户滑动表头*/
        .header {
            touch-action: pan-y;
        }


        .on {
            background: #F5F7FA;
        }

        .off {
            background: white;
        }

        .custom-table--body-wrapper {
            overflow: hidden;
        }

        .custom-table--header-wrapper {
            overflow: hidden;
        }
        .custom-table--fixed-wrapper {
            position: absolute;
            left: 3px;
            /*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同,否则会错位*/
            top: 123px;
            bottom: 0;
            background-color: #f8f8f8;
            /*用于覆盖底下的table*/
            z-index: 0;

            width: 93px;
        }
</style>

js函数:不变

效果:

七:固定多列

就变一下css样式

css样式:

  .custom-table--fixed-wrapper {
            position: absolute;
            left: 3px;
            /*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同*/
            top: 123px;
            bottom: 0;
            background-color: #f8f8f8;
            /*用于覆盖底下的table*/
            z-index: 0;

            /*这个值用于覆盖多少列,就是固定多少列*/
            width: 280px;
        }

效果

:

 八:固定表头:

其他不变

添加一个jquery函数:用于调节固定的位置这些参数

 $(function () {
        $('.body').on('scroll', function () {
            let left = $(this).scrollLeft();
            $('.header').scrollLeft(left);
        });
        var tab_top = $('.header').offset().top;
        $(window).scroll(function () {
            var scroH = $(this).scrollTop();
            /*35是悬浮位置距离浏览器顶部的高度*/
            if (scroH > tab_top-35) {
                $(".header").css("position", "fixed");
                $(".custom-table--header-wrapper").css("position", "fixed");
                $(".header").css("top", "35px");
                $(".custom-table--header-wrapper").css("top", "35px");
                /*这个数和固定列的宽度一样.custom-table--fixed-wrapper*/
                $(".custom-table--header-wrapper").css("width", "95px");
                /*这个颜色和之前的表头背景色要一样*/
                $(".header").css("background-color", "#f8f8f8");
                $(".custom-table--header-wrapper").css("background-color", "#f8f8f8");
            } else {
                $(".header").css("position", "relative");
                $(".custom-table--header-wrapper").css("position", "relative");
            }
        });
    });

效果:

:

时间匆忙,实现所有效果的情况,有bug,慎用:

比如,固定列和定位靠手动去写多少px,这不科学吧,

左下角穿透底部菜单了 ,从顶部往下滑,表头位置已经不对了 ,比初始下降了一点,导致表体第一行数据被遮挡:

不过这些问题,应该都是很好解决的.

组件源码(很简单就是几个div中放几个插槽):

var mybody = `
<div class="body">
 <slot></slot>
</div>
`

var myhead = `
<div class="header">
<slot></slot>
</div>
`
var myfix = `
<div class="custom-table--fixed-wrapper">
<div class="custom-table--header-wrapper" >
<slot name="fixhead"></slot>
</div>
<div class="custom-table--body-wrapper">
<slot></slot>
</div>
</div>
`


var myBody = {
        template: mybody,
    }
;
var myHead = {
        template: myhead,
    }
;
var myFix = {
        template: myfix,

    }
;


Vue.component('my-body', myBody);
Vue.component('my-head', myHead);
Vue.component('my-fix', myFix);
Vue.component('gen-head', {
    props: ["head"],
    template: genhead,
});
Vue.component('gen-body', {
    props: ["tableData"],
    template: genbody,
});


有问题,欢迎指正批评

 

 

2019年6月7日01:09:02补充:

以上左下角穿透bug:z-index=100可解决

css样式:

<style>
        table {
            width: 750px;
        }

        .body {
            width: 375px;
            overflow: scroll;
            /*这个值要比悬浮div小*/
            z-index: -100;
        }

        .header {
            width: 375px;
            overflow: scroll;
        }

        tr {
            height: 40px;
        }

        td {
            border: 1px solid #ebeef5;
            word-break: break-all;
            text-align: center;
            padding: 0px;
            vertical-align: middle;
        }

        /*用于阻止用户滑动表头*/
        .header {
            touch-action: pan-y;
        }


        .on {
            background: #F5F7FA;
        }

        .off {
            background: white;
        }

        .custom-table--body-wrapper {
            overflow: hidden;
        }

        .custom-table--header-wrapper {
            overflow: hidden;
            /*用于解决左下角穿透底部菜单问题*/
            z-index: 99;

        }

        .custom-table--fixed-wrapper {
            position: absolute;
            left: 3px;
            /*这个值就是table距离顶部的一个距离,如果页面上有引起table位置变化的因素,那么这个值应该取一个变量和table距离顶部的高度相同*/
            top: 123px;
            bottom: 0;
            background-color: #f8f8f8;
            /*用于覆盖底下的table比body大,比他上面的元素要小*/


            /*这个值用于覆盖多少列,就是固定多少列*/
            /*覆盖两列的宽度*/
            /*width: 280px;*/
            /*覆盖一列的宽度*/
            width: 95px;
        }
</style>

 

固定列遮挡第一列问题:解决代码如下:

<script>
  $(function () {
        $('.body').on('scroll', function () {
            let left = $(this).scrollLeft();
            $('.header').scrollLeft(left);
        });
        var tab_top = $('.header').offset().top;
        $(window).scroll(function () {
            var scroH = $(this).scrollTop();
            /*35是悬浮位置距离浏览器顶部的高度*/
            if (scroH > tab_top - 35) {
                $(".header").css("position", "fixed");
                $(".custom-table--header-wrapper").css("position", "fixed");
                $(".header").css("top", "35px");
                $(".custom-table--header-wrapper").css("top", "35px");
                /*这个数和固定列的宽度一样.custom-table--fixed-wrapper*/
                $(".custom-table--header-wrapper").css("width", "95px");
                /*这个颜色和之前的表头背景色要一样*/
                $(".header").css("background-color", "#f8f8f8");
                $(".custom-table--header-wrapper").css("background-color", "#f8f8f8");
            } else {
                $(".header").css("position", "relative");
            /*解决第一行被相对定位的表头遮挡问题*/
                $(".header").css("top", "0px");
                $(".custom-table--header-wrapper").css("position", "relative");
            /*解决第一行被相对定位的表头遮挡问题*/
                $(".custom-table--header-wrapper").css("top", "0px");
            }
        });
    });
</script>

其他问题:

各种浏览器 ,各种 分辨率设备,兼容性问题,横屏问题,有待解决,z-inde=99解决了左下角穿透问题,设置相对定位的 top属性解决了 表头遮挡表体第一行问题,还有不能手写px问题,应该交给js去得到合适的数值,设置合适的数值,而不是手动去赋值!!!

 

最终效果如下:

 最后故意触发那个bug,就是通过点击查询最右边那个大于号,展开了查询条件,导致表格位置发生了变化,而固定列悬浮的div,并没有感受到变化,导致错位,这也是一个bug,也就是说当页面有改变表格位置的动作时,表格固定列和表格其他部分会错位

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值