美文网首页程序猿的纸条屋
vue移动端表格,可横行滚动,固定表头,列

vue移动端表格,可横行滚动,固定表头,列

作者: __Nancy | 来源:发表于2020-06-16 20:51 被阅读0次

    先看效果图


    效果图.gif
    第一步:引入 iscroll
    npm i iscroll --save 
    
    第二步:封装

    对插件再做一层封装,封装成 iscrollTable.js 方便调用,代码如下:

    // 统一使用
    const IScollProbe = require('iscroll/build/iscroll-probe');
    
    let scroller = null;
    let Selector = '';
    export function createIScroller(selector) {
      Selector = selector;
      scroller = new IScollProbe(Selector, {
        preventDefault: false, // 阻止浏览器滑动默认行为
        probeType: 3, // 需要使用 iscroll-probe.js 才能生效 probeType : 1 滚动不繁忙的时候触发 probeType : 2 滚动时每隔一定时间触发 probeType : 3   每滚动一像素触发一次
        mouseWheel: true, // 是否监听鼠标滚轮事件。
        scrollX: true, // 启动x轴滑动
        scrollY: true, // 启动y轴滑动
        // momentum: false,
        lockDirection: false,
        snap: false, // 自动分割容器,用于制作走马灯效果等。Options.snap:true// 根据容器尺寸自动分割
        // snapSpeed: 400,
        scrollbars: false, // 是否显示默认滚动条
        freeScroll: true, // 主要在上下左右滚动都生效时使用,可以向任意方向滚动。
        deceleration: 0.0001, // 滚动动量减速越大越快,建议不大于 0.01,默认:0.0006
        disableMouse: true, // 是否关闭鼠标事件探测。如知道运行在哪个平台,可以开启它来加速。
        disablePointer: true, // 是否关闭指针事件探测。如知道运行在哪个平台,可以开启它来加速。
        disableTouch: false, // 是否关闭触摸事件探测。如知道运行在哪个平台,可以开启它来加速。
        eventPassthrough: false, // 使用 IScroll 的横轴滚动时,如想使用系统立轴滚动并在横轴上生效,请开启。
        bounce: false, // 是否启用弹力动画效果,关掉可以加速
      });
    
      function updatePosition() {
        const frozenCols = document.querySelectorAll(`${selector} table tr td.cols`);
        const frozenRows = document.querySelectorAll(`${selector} table tr th.rows`);
        const frozenCrosses = document.querySelectorAll(`${selector} table tr th.cross`);
        for (let i = 0; i < frozenCols.length; i++) {
          frozenCols[i].style.transform = `translate(${-1 * this.x}px, 0px) translateZ(0px)`;
        }
        for (let i = 0; i < frozenRows.length; i++) {
          frozenRows[i].style.transform = `translate(0px, ${-1 * this.y}px) translateZ(0px)`;
        }
        for (let i = 0; i < frozenCrosses.length; i++) {
          frozenCrosses[i].style.transform = `translate(${-1 * this.x}px,${-1 * this.y}px) translateZ(0px)`;
        }
      }
      scroller.on('scroll', updatePosition);
      scroller.on('scrollEnd', updatePosition);
      scroller.on('beforeScrollStart', () => {
        scroller.refresh();
      });
    
      return scroller;
    }
    
    export function refreshScroller() {
      if (scroller === null) {
        console.error('先初始化scroller');
        return;
      }
      setTimeout(() => {
        scroller.refresh();
        scroller.scrollTo(0, 0);
        const frozenCols = document.querySelectorAll(`${Selector} table tr td.cols`);
        const frozenRows = document.querySelectorAll(`${Selector} table tr th.rows`);
        const frozenCrosses = document.querySelectorAll(`${Selector} table tr th.cross`);
        for (let i = 0; i < frozenCols.length; i++) {
          frozenCols[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
        }
        for (let i = 0; i < frozenRows.length; i++) {
          frozenRows[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
        }
        for (let i = 0; i < frozenCrosses.length; i++) {
          frozenCrosses[i].style.transform = 'translate(0px, 0px) translateZ(0px)';
        }
      }, 0);
    }
    export function destroyScroller() {
      if (scroller === null) {
        return;
      }
      scroller.destroy();
      scroller = null;
    }
    
    第三步:页面使用

    引用前面的自己封装的iscrollTable.js,用到的table.vue的具体代码如下:

    <template>
        <div class="pages-tables " id="pages-tables">
            <div class="waterMask" id="watermark"></div>
            <div class="rolling-table meal-table" ref="tableBox" :style="{height: maxHeight + 'px'}">
                <table class="table" id="table" cellpadding="0" cellspacing="0" ref="rollingTable">
                    <tr v-for="(x,i) in xList" :key="i">
                        <th class="rows " :class="{'cross': index == 0 && i == 0}" v-for="(l,index) in x" :key="index" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th>
                    </tr>
                   <tr v-for="(l,i) in yList" :key="i + 'a'">
                        <template v-for="(x, xKey) in xField" >
                           <template v-for="(ll,yKey) in l">
                              <td  :key="xKey+yKey" v-if="x === yKey" :class="{'cols': yKey == xField[0]|| yKey == xField[1]}">
                                  {{ yList[i][yKey]}}
                              </td>
                             </template>
                        </template>
                    </tr>
                    <tr></tr>
                </table>
            </div>
        </div>
    </template>
    <script>
    //demo中没有用到refreshScroller,当需要刷新回到页面顶部时调用
    import { createIScroller, refreshScroller, destroyScroller } from "libs/iscrollTable";
    export default {
        data() {
            return {
                maxHeight:'100%',
                scroll: {
                    scroller: null
                },
                xList: [
                    [
                        {
                            field_name: "statis_date",
                            name: "第一行合并3行1列",
                            colspan: 1, //指定单元格 横向 跨越的 列数
                            rowspan: 3, //指定单元格 纵向 跨越的 行数
                        },
                        {
                            field_name: "custom_field",
                            name: "第一行合并2列",
                            colspan: 2,
                            rowspan: 1,
                        },
                        {
                            field_name: "custom_field",
                            name: "第一行合并2列",
                            colspan: 2,
                            rowspan: 1,
                        },
                        {
                            field_name: "custom_field",
                            name: "第一行合并3列",
                            colspan: 3,
                            rowspan: 1,
                        },
                    ],
                    [
                        {
                            field_name: "custom_field",
                            name: "第二行日期",
                            colspan: 1, //指定单元格 横向 跨越的 列数
                            rowspan: 1, //指定单元格 纵向 跨越的 行数
                        },
                        {
                            field_name: "custom_field",
                            name: "第二行日期合并2列",
                            colspan: 2,
                            rowspan: 1,
                        },
                        {
                            field_name: "custom_field",
                            name: "第二行日期合并2列",
                            colspan: 2,
                            rowspan: 1,
                        },
                        {
                            field_name: "custom_field",
                            name: "第二行日期合并3列",
                            colspan: 3,
                            rowspan: 1,
                        },
                    ],
                    [
                        {
                            field_name: "area_name",
                            name: "第三行当月新增",
                            colspan: 1,  //指定单元格 横向 跨越的 列数
                            rowspan: 1, //指定单元格 纵向 跨越的 行数
                        },
                        {
                            field_name: "area_name1",
                            name: "第三行当月新增1",
                            colspan: 1,
                            rowspan: 1,
                        },
                        {
                            field_name: "area_name2",
                            name: "第三行当月新增2",
                            colspan: 1,
                            rowspan: 1,
                        },
                        {
                            field_name: "area_name3",
                            name: "第三行当月新增3",
                            colspan: 1,
                            rowspan: 1,
                        },
                        {
                            field_name: "area_name4",
                            name: "第三行当月新增4",
                            colspan: 1,
                            rowspan: 1,
                        },
                        {
                            field_name: "area_name5",
                            name: "第三行当月新增5",
                            colspan: 1,
                            rowspan: 1,
                        },
                        {
                            field_name: "area_name6",
                            name: "第三行当月新增6",
                            colspan: 1,
                            rowspan: 1,
                        },
                    ],
                ],
                xField: ['statis_date', 'area_name', "area_name1", "area_name2", "area_name3", "area_name4", "area_name5", "area_name6",],
                yList: [
                    {
                        area_name: "新增数据开始",
                        area_name1: "新增数据开始1",
                        area_name2: "新增数据开始2",
                        area_name3: "新增数据开始3",
                        area_name4: "新增数据开始4",
                        area_name5: "新增数据开始5",
                        area_name6: "新增数据开始6",
                        statis_date: 100007,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据",
                        area_name1: "新增数据1",
                        area_name2: "新增数据2",
                        area_name3: "新增数据3",
                        area_name4: "新增数据4",
                        area_name5: "新增数据5",
                        area_name6: "新增数据6",
                        statis_date: 201807,
                    },
                    {
                        area_name: "新增数据最后",
                        area_name1: "新增数据最后1",
                        area_name2: "新增数据最后2",
                        area_name3: "新增数据最后3",
                        area_name4: "新增数据最后4",
                        area_name5: "新增数据最后5",
                        area_name6: "新增数据最后6",
                        statis_date: 222222,
                    }
                ]
            }
        },
        mounted() {
            this.maxHeight = window.screen.height
            this.scroll.scroller = createIScroller(".meal-table");
            // addWaterMarker(document.getElementById('watermark'))
        },
        beforeDestroy() {
          destroyScroller();
        },
    }
    
    </script>
    <style lang="less" scoped>
    .pages-tables {
      -webkit-overflow-scrolling: touch; // ios滑动顺畅
      position: relative;
    }
    .rolling-table {
        height: 100%;
        font-size: 0.28rem;
        color: #86939a;
        background-color: #fff;
        width: 100%;
        -webkit-overflow-scrolling: touch;
        position: relative;
        top: 0;
        overflow: hidden;
      }
    .rows {
        position: relative;
        z-index: 3;
    }
    .cross {
        position: relative;
        z-index: 5;
    }
    table td {
      border: 0px solid #000;
      font-size: 0.32rem;
      background: #fff;
    }
    ::-webkit-scrollbar {
        display: none;
    }
    .table {
    //   border-collapse: collapse; //去掉重复的border
      color: #86939e;
      font-size: 0.32rem;
      border: 0px solid #000;
      min-height: 100%;
      text-align: center;
      td {
        border-bottom: 0.02rem solid #eee;
        white-space: nowrap;
        height: 0.86rem;
        line-height: 0.86rem;
        padding: 0 0.2rem;
      }
      th {
        color: #43484d;
        white-space: nowrap;
        height: 0.74rem;
        line-height: 0.74rem;
        padding: 0rem 0.3rem;
        background-color: #f3f4f6;
        font-weight: normal;
        padding-bottom: 0;
        padding-top: 0;
        border: 0.02rem solid red;
      }
    }
    tr{
        position: relative;
        background-color: #fff;
        &:nth-of-type(odd){
            td{
                // background-color: pink;
            }
        }
    }
    </style>
    

    注意:
    如果页面中需要多个列固定,参考下图:


    image.png

    如果帮组到您,请举小手手赞一下,笔芯 ❤❤❤

    相关文章

      网友评论

        本文标题:vue移动端表格,可横行滚动,固定表头,列

        本文链接:https://www.haomeiwen.com/subject/zifvahtx.html