#前言
最近做移动端的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.0006disableMouse: 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的具体代码如下:

<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"><td v-for="(ll,yKey) in l" :key="yKey" v-if="x === yKey" :class="{'cols': yKey == xField[0]}">{{ yList[i][yKey]}}</td></template></tr><tr></tr></table></div></div>
</template>
<script>
import { createIScroller, refreshScroller } from "libs/iscrollTable";
import { addWaterMarker } from "libs/common/common";
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.heightthis.scroll.scroller = createIScroller(".meal-table");// addWaterMarker(document.getElementById('watermark'))}
}</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; //去掉重复的bordercolor: #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>

注意点:

  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的左右滚动。

完整代码如下:

<template><div class="pages" id="pages" :style="{height: maxHeight + 'px'}"><table id="table" class="table" cellpadding="0" cellspacing="0"><thead v-show="showFixedHeaderCloFirst" class="fixedThead" id="fixedThead" :style="{left: fixedTheadLeft}"><tr v-for="(x,i) in xList"   :key="i+'a'"><th v-for="(l,i) in x" :key="i" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th></tr></thead><div v-show="showFixedHeaderCloFirst" class="fixedHeaderCenter" id="fixedHeaderCenter" :style="{'line-height': firstCloHeight + 'px',width: firstCloWidth-1 + 'px'}">{{xList[0][0].name}}</div><tbody v-show="showFixedHeaderCloFirst" class="fixedHeaderCloFirst" id="fixedHeaderCloFirst" :style="{'top': fixedHeaderCloFirstTop ,'height': fixedHeaderCloFirstHeight}"><tr v-for="(l,i) in yList" :key="i" :style="{width: firstCloWidth + 'px',height: cloFirstLineHeight + 'px'}"><td :style="{width: firstCloWidth + 'px',height: cloFirstLineHeight -1 + 'px' }">{{l.statis_date }} </td></tr></tbody><thead ><tr v-for="(x,index) in xList"   :key="index+'b'"><th :class="{firstCol: index == 0 && i == 0}" v-for="(l,i) in x" :key="i" :colspan="l.colspan" :rowspan="l.rowspan">{{l.name}}</th></tr></thead><tbody id="tbody"><tr  v-for="(l,i) in yList" :key="i"><td v-for="(x,xKey) in xField" :key="xKey"><div v-for="(ll,yKey) in l" v-if="x === yKey" :key="yKey" :class="{'tables-content-item-yellow':yList[i][yKey] > 0 && validateVal(x),'tables-content-item-green':yList[i][yKey] <= 0 && validateVal(x),}">{{ yList[i][yKey]}}</div></td></tr></tbody></table></div>
</template>
<script>
export default {data() {return {maxHeight: '100%',fixedTheadLeft: 0,fixedHeaderCloFirstTop: 0,fixedHeaderCloFirstHeight: '100%',th: [],tl: [],temp: [],firstCloWidth: 0,firstCloHeight: 0,showFixedHeaderCloFirst: false,cloFirstLineHeight: '0',fixedCol: false,fixedHeader: false,fixedA1: false,hLeft: 0,hHeight: 0,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,}]}},filters: {dateFromt: function (value) {if (!value) return ''value = value.toString()return value.slice(4)},},methods: {// 返回vdVal(val, value) {return value},// 是否包含 % 标志,有就要颜色控制validateVal(value) {let flag = falsethis.xList.forEach((e, i) => {if (e.zd_name == value) {if (e.zx_name.includes('%')) {flag = true}}})return flag},$$(dom){return document.getElementById(dom)},savePosition(){this.maxHeight = window.screen.heightthis.$$("pages").onscroll = (()=> {let offsetHeight = this.$$("fixedHeaderCenter").offsetHeightlet scrollTop = offsetHeight + 1 - this.$$("pages").scrollTopthis.fixedTheadLeft =  - this.$$("pages").scrollLeft + 'px'this.fixedHeaderCloFirstTop = scrollTop + 'px'console.log("scrollTop:",scrollTop)console.log("this.fixedHeaderCloFirstTop:",this.fixedHeaderCloFirstTop)});// this.$$("fixedHeaderCloFirst").onscroll = (()=> {//     let offsetHeight = this.$$("fixedHeaderCenter").offsetHeight//     let scrollTop = - this.$$("fixedHeaderCloFirst").scrollTop//     this.$$("pages").style.left =  - this.$$("fixedHeaderCloFirst").scrollLeft + 'px'//     this.$$("table").style.top =  scrollTop + 'px'// });}},mounted() {setTimeout(()=>{this.firstCloWidth = document.getElementsByClassName("firstCol")[0].offsetWidth this.firstCloHeight = document.getElementsByClassName("firstCol")[0].offsetHeight-1this.fixedHeaderCloFirstHeight = this.$$("tbody").offsetHeight + 'px'this.cloFirstLineHeight = this.$$("tbody").children[0].offsetHeight  + 'px'this.fixedHeaderCloFirstTop = this.firstCloHeight + 3 + 'px'this.showFixedHeaderCloFirst = truethis.savePosition()},1000)},
}</script>
<style lang="less" scoped>
::-webkit-scrollbar {display: none;
}
.pages{overflow: scroll;height: 100%;}
.fixedHeaderCenter{border: 1px solid red;background-color: #f3f4f6;color: #43484d;text-align: center;// padding: 0 0.3rem;position: fixed;left: 0;top: 0;z-index: 9999;
}
.fixedHeaderCloFirst{// border-bottom: 1px solid #eee;height: 100%;line-height: 0.86rem;background: #fff;white-space: nowrap;text-align: center;position: fixed;left: 0;top: 0;th,td{padding: 0;}// overflow: scroll;div{background-color: #fff;border-bottom: 1px solid #eee;}
}
@main-color-green: #269513;
@main-color-yellow: #fc9d2e;
table {position: relative;color: #86939e;font-size: 0.32rem;border: 0px solid #000;min-height: 100%;text-align: center;white-space:nowrap;td {border-bottom: 1px solid #eee;white-space: nowrap;height: 0.86rem;line-height: 0.86rem;padding: 0 0.2rem;white-space:nowrap;}th {white-space:nowrap;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: 1px solid red;}
}
.tables-content-item-green {color: @main-color-green;
}.tables-content-item-yellow {color: @main-color-yellow;
}
table {font-size: 0.3rem;// margin: 300px;border-collapse:collapse
}
.fixedThead{background: lightblue;position: fixed;top: 0 ;z-index: 2;
}
/*固定表头的样式*/
.fixedHeader {background: lightblue;position: fixed;top: 0 ;z-index: 2;
}</style>

最终效果图如下:

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

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

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

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

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

  1. vue 移动端table表格 固定首列和首行(简单粗暴)

    效果图,不会做gif...只有静态预览: 上下滑动的时候固定了顶部,并且往左滑的时候冻结了第一列. 代码 :  主要原理就是用 position: sticky;这个属性,粘在top==0px的时候. ...

  2. Vue 前端导出Excel表格,多级表头合并

    针对有Excel导出经验 安装依赖 npm install --save xlsx file-saver 引入以下文件 Blob.js /* eslint-disable */ /* Blob.js* ...

  3. Vue使用Export2Excel导出表格时隐藏表头

    真实需求并不是要隐藏表头,而是因为后端返回的数据就把表头给拼上去了... 所以不能再加一个header. 直接再代码中不写header,会报错 excel.export_json_to_excel({ ...

  4. vue 竖向纵向仿表格 动态渲染表头表格 根据id填充单元格

    关于布局这里不多说,上篇为此发过一篇,因需求布局稍微改动一下.移步至布局篇.如产品所说,一些数据是已封装好的,最后不要轻易动,既然这样.原本简单的需求必须由多接口返回数据,前端进行拼接并填充.后端提供 ...

  5. el table 固定表头和首行_vue表格实现固定表头首列

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

  6. element-ui 表格(table)合并表头下面合并列且可以收缩展开

    百度了一大堆,发现了首行不能合并,想到了用dom做,找到了下面这个链接 要点记录: 1.表头合并 -- 给table添加属性:header-cell-style="headerStyle&q ...

  7. BootStrap自适应Table表格固定左边第一列

    有个页面引用了BootStrap前端框架,这个页面是一个table,要放在手机上浏览.这个table的左侧第一列是要固定的.所谓第一列固定,就是在横向滚动的时候第一列一直显示在最左侧.网上查了下方法, ...

  8. vue项目中table表格固定表头和首尾列

    在html中实现table表格固定表头和首尾列的方法和文章很多,本文就不再赘述. 本文主要介绍vue项目中三种情景下实现table表格固定表头和首尾列 情景一:vue+element 只要在el-ta ...

  9. vue表格实现固定表头首列

    ​​​​​​​下载地址 vue表格实现固定表头首列 dd:

  10. vue移动端表格吸顶、行自适应高度、列左侧固定悬浮

    简介 1.表头吸顶效果 2.左侧列固定,右侧滑动,表头跟随内容滑动 3.行高自适应 番外 最近上海疫情,居家办公一月多了,愿阴霾散去.最近网上在正常得市民抱怨中,有很多别有用心之人,数典忘祖,造谣生事 ...

最新文章

  1. 基于OpenCV修复表格缺失的轮廓--如何识别和修复表格识别中的虚线
  2. 【转】AVAudioPlayer播放音乐,最清晰明了
  3. saltstack之(一)系统环境及本地yum源
  4. mybatis 配置_MyBatis教程3:优化MyBatis配置文件中的配置
  5. [ python ] 正则表达式及re模块
  6. HttpServletRequest常用获取URL的方法
  7. python3中朴素贝叶斯_贝叶斯统计:Python中从零开始的都会都市
  8. 【Spring 】启动报错 LoggerFactory is not a Logback LoggerContext but Logback...
  9. 45本Hadoop、大数据方向书籍,包邮送到家!
  10. oracle添加男女约束,Oracle如何给数据库添加约束过程解析
  11. Java面试:mysql批量更新
  12. Himawari-8 数据介绍及下载方法
  13. 电脑未安装任何音频设备解决办法
  14. python的opencv操作记录(七)——短时傅里叶变换(stft)
  15. 小盒即时通讯IM-全套开源-开箱即用
  16. Latex入门_第3章:文档元素
  17. 网络安全宣传月安全团队需要知道的关于PKI的九件事
  18. 电脑上录屏的软件有哪些,屏幕录制软件哪个好用
  19. 微信小程序中数字取整
  20. OpenShift从入门到精通系列之一:通过OpenShift实现数字化转型

热门文章

  1. java 一元二次方程_Java类求解一元二次方程的根
  2. C/C++整数除法以及保留小数位的问题
  3. 科研论文检索方法入门(计算机领域)
  4. 平面设计中的对比设计技巧
  5. 计算机最小的计量单位,计算机中最小的计量单位是
  6. IDEA修改某个文件的编码
  7. 为什么央行降息降准,会导致债券价格上涨?
  8. 《鹰猎长空》看世界范围内电影票价上涨的原因
  9. 新手搭建一个网站(详细完整版)
  10. 反爬虫破解——裁判文书网