vue移动端复杂表格表头,固定表头与固定第一列


#前言
最近做移动端的h5项目,要做一个可配置表头的复杂表格,网上找了很久也没什么好方法,结合网上的一些例子,在此做一了一个完整的vue版的例子。
#效果
无图无真相,先上最终效果图再说 。

#方法一:iscroll 插件版
###第一步:npm install
引入 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 //是否启用弹力动画效果,关掉可以加速
  });
  scroller.on('scroll', updatePosition);
  scroller.on('scrollEnd', updatePosition);
  scroller.on('beforeScrollStart', function () {
    scroller.refresh();
  });

  function updatePosition() {
    let frozenCols = document.querySelectorAll(selector + ' table tr td.cols');
    let frozenRows = document.querySelectorAll(selector + ' table tr th.rows');
    let 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)';
    }
  }

  return scroller;
}

export function refreshScroller() {
  if (scroller === null) {
    console.error("先初始化scroller");
    return;
  }
  setTimeout(() => {
    scroller.refresh();
    scroller.scrollTo(0, 0);
    let frozenCols = document.querySelectorAll(Selector + ' table tr td.cols');
    let frozenRows = document.querySelectorAll(Selector + ' table tr th.rows');
    let 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);
}

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




注意点:

  1. table 外的盒子 .rolling-table 要设置高度,不然向上滚动失效
    2.固定和行与列,即:rows、cross 的position要设为relative

最终效果就如上图。
#方法二: 结合css,自定义封装版
###原理
因为除了表头和第一列,其他都可以滚动所以需要:
1.一个展示的table表格
2.一个用来覆盖上表头的 thead,一个用来覆盖左上角的 div,一个固定在第一列的 tbody。
3. 展示的table表格放在最底层,覆盖上表头的 thead固定定位在最上面,固定在第一列的 tbody固定定位在最左边,左上角的 div固定是左上角且z-index最大,在最上层。
4. 固定的表格头部与第一列的宽、高、行高都是通过获取真实的表格的宽高来设定的。
5. 通过展示的table表格的上下滚动从而带动固定在第一列的 tbody向上滚动,向左右滚动带动覆盖上表头的 thead的左右滚动。

完整代码如下:




最终效果图如下:

不过这个版本的上下滚动时的精准计算有点误差。
####推荐第一种方式。

#最后
希望文章内容对你有一点帮助!

欢迎关注以下公众号,学到不一样的 武功秘籍

关注公众号并回复 福利 可领取免费学习资料,福利详情请猛戳: 免费资源获取–Python、Java、Linux、Go、node、vue、react、javaScript

你可能感兴趣的:(前端)