亲测苹果电脑,chrome浏览器无卡顿现象,其它浏览器并未测试,如遇到卡顿请备注系统和浏览器,方便我后续优化,谢谢vue
先看一下效果,一共1000 X 100 = 10W
个单元格基本感觉不到卡顿,并且每一个单元格点击能够编辑,支持固定头和固定列jquery
Star
一下,哪里有问题也欢迎指出,感谢笔者最近在作广告排期功能,须要进行点位预占,大的合同可能须要对多个资源排期,周期可能到几年这样,而后咱们的页面交互是这样git
横向每月30个单元格,最多的3年,36个月,每行36*30=1080个单元格github
竖向100个资源,总共约️10W个单元格,而后每一个单元格里面会有一个输入框,一个库存总数,因此总数是20W个,内网使用,接口请求根本不是问题,能够浏览器渲染就扛不住了接口回来以后会出现几十秒的白屏,整个页面处于卡死状态chrome
这还不算,加载出以后页面操做也是很是卡,滑动延迟严重,页面基本处于瘫痪状态json
以前的功能是基于jquery开发的,项目重构用的vue,UI采用了ElementUI,ElmentUI中的表格在数据量较大是有严重的性能问题,最直接的表现就是白屏时间较长,并且会出现渲染错乱浏览器
因此就想着本身实现一个表格,解决卡顿问题bash
表格横向按月拆分,每月份单独一个table,月份table外层放一个占位div,根据横向滚动位置控制展现dom
竖向按资源拆分,一样包裹一个占位div,按照滚动位置动态加载,始终保持dom数量上线
方案就是点击单元格展现输入框,焦点丢失移除,此处的展现非display控制显示隐藏,而是v-if控制dom是否加载
<div class="table-head">
<div class="module"
v-bind:style="{ transform: 'translateX(' + scrollLeft + 'px)' }"
v-for="(item, index) in monthData" v-bind:key="index">
<table cellspacing="0" cellpadding="0">
<thead>
<tr>
<td colspan="30">{{item.month}}</td>
</tr>
<tr>
<td width="100"
v-for="(d_item, d_index) in item.days" v-bind:key="d_index"
style="min-width:100px">{{d_item}}</td>
</tr>
</thead>
</table>
</div>
</div>
复制代码
<div class="table-fix-cloumns">
<div class="module fix-left-top">
<table width="100" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td>位置</td>
</tr>
<tr>
<td>position</td>
</tr>
</thead>
</table>
</div>
<div class="module" v-bind:style="{ transform: 'translateY(' + scrollTop + 'px)' }">
<table width="100" cellspacing="0" cellpadding="0">
<thead>
<tr v-for="(item, index) in projectData" v-bind:key="index">
<td>{{item.name}}</td>
</tr>
</thead>
</table>
</div>
</div>
复制代码
<div class="table-body" @scroll="tableScroll" style="height: 300px">
<div class="module"
style="width:3000px;"
v-for="(item, index) in monthData" v-bind:key="index">
<div class="content"
v-if="Math.abs(index - curModule) < 3">
<div class="row"
style="height:30px"
v-for="(p_item, p_index) in projectData"
v-bind:key="p_index">
<table width="3000"
v-if="Math.abs(p_index - curRow) < 20"
cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td
@click="clickTd(p_index,item.month, d_item, $event)"
v-for="(d_item, d_index) in item.days" v-bind:key="d_index">
<span v-if="!originProjectData[p_index][''+item.month][''+d_item]['show']">{{originProjectData[p_index][''+item.month][''+d_item]['last']}}</span>
<input
@blur="blurTd(p_index,item.month, d_item)"
v-if="originProjectData[p_index][''+item.month][''+d_item]['show']"
v-model="originProjectData[p_index][''+item.month][''+d_item]['last']"
v-focus="originProjectData[p_index][''+item.month][''+d_item]['focus']"/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
复制代码
通过如上优化,完美解决表格卡顿问题,可是我并无封装组件,缘由以下
·插件封装后会有不少限制,不能再用vue那种模板写法,用json传入数据,自定义内容不是很灵活
·能够根据本身的应用场景自行修改拓展,代码已经很简洁
·比较懒
复制代码