前言
最近做移动端的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的具体代码如下:
<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.height this.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; //去掉重复的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>
注意点:
- table 外的盒子 .rolling-table 要设置高度,不然向上滚动失效
2.固定和行与列,即:rows、cross 的position要设为relative
最终效果就如上图。
方法二: 结合css,自定义封装版
原理
因为除了表头和第一列,其他都可以滚动所以需要:
1.一个展示的table表格
2.一个用来覆盖上表头的 thead,一个用来覆盖左上角的 div,一个固定在第一列的 tbody。
- 展示的table表格放在最底层,覆盖上表头的 thead固定定位在最上面,固定在第一列的 tbody固定定位在最左边,左上角的 div固定是左上角且z-index最大,在最上层。
- 固定的表格头部与第一列的宽、高、行高都是通过获取真实的表格的宽高来设定的。
- 通过展示的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 = false this.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.height this.$$("pages").onscroll = (()=> { let offsetHeight = this.$$("fixedHeaderCenter").offsetHeight let scrollTop = offsetHeight + 1 - this.$$("pages").scrollTop this.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-1 this.fixedHeaderCloFirstHeight = this.$$("tbody").offsetHeight + 'px' this.cloFirstLineHeight = this.$$("tbody").children[0].offsetHeight + 'px' this.fixedHeaderCloFirstTop = this.firstCloHeight + 3 + 'px' this.showFixedHeaderCloFirst = true this.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>
最终效果图如下:
不过这个版本的上下滚动时的精准计算有点误差。