vue大数据表格卡顿问题的完美解决方案

 更新时间:2019年03月20日 14:45:31   作者:杨金凯  
这篇文章主要给大家介绍了基于vue大数据表格卡顿问题的完美解决方案,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

vue渲染小数据挺快,大数据vue开始出现卡顿现象,本文讲给大家详细介绍关于vue大数据表格卡顿问题的解决方法

点我在线体验Demo(请用电脑查看)

亲测苹果电脑,chrome浏览器无卡顿现象,其它浏览器并未测试,如遇到卡顿请备注系统和浏览器,方便我后续优化,谢谢

先看一下效果,一共1000 X 100 = 10W个单元格基本感受不到卡顿,而且每个单元格点击可以编辑,支持固定头和固定列

项目源代码地址 Github (本地下载)

解决问题核心点:横向滚动加载,竖向滚动加载

项目背景

笔者最近在做广告排期功能,需要进行点位预占,大的合同可能需要对多个资源排期,周期可能到几年这样,然后我们的页面交互是这样

横向每个月30个单元格,最多的3年,36个月,每行36*30=1080个单元格

竖向100个资源,总共约️10W个单元格,然后每个单元格里面会有一个输入框,一个库存总数,所以总数是20W个,内网使用,接口请求根本不是问题,可以浏览器渲染就扛不住了接口回来之后会出现几十秒的白屏,整个页面处于卡死状态

这还不算,加载出之后页面操作也是非常卡,滑动延迟严重,页面基本处于瘫痪状态

之前的功能是基于jquery开发的,项目重构用的vue,UI采用了ElementUI,ElmentUI中的表格在数据量较大是有严重的性能问题,最直接的表现就是白屏时间较长,而且会出现渲染错乱

所以就想着自己实现一个表格,解决卡顿问题

实现思路

表格拆分,动态加载

表格横向按月拆分,每个月份单独一个table,月份table外层放一个占位div,根据横向滚动位置控制展示

竖向按资源拆分,同样包裹一个占位div,按照滚动位置动态加载,始终保持dom数量上线

动态编辑,按需生成编辑输入框

不同的标签在浏览器渲染时性能是不一样的,比如input这种标签就比span等标签重许多,所以不能满屏input

方案就是点击单元格展示输入框,焦点丢失移除,此处的展示非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传入数据,自定义内容不是很灵活
·可以根据自己的应用场景自行修改拓展,代码已经很简洁
·比较懒

如果你有类似需求可以试一下我这个,也欢迎Star

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

相关文章

  • Vuex之理解Getters的用法实例

    Vuex之理解Getters的用法实例

    这篇文章主要介绍了Vuex之理解Getters的用法实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 简单了解vue中父子组件如何相互传递值(基础向)

    简单了解vue中父子组件如何相互传递值(基础向)

    这篇文章主要介绍了简单了解vue中父子组件如何相互传递值(基础向),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Vue脚手架学习之项目创建方式

    Vue脚手架学习之项目创建方式

    这篇文章主要给大家介绍了关于Vue脚手架学习之项目创建方式的相关资料,文中通过介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 使用Vue父子组件通信实现todolist的功能示例代码

    使用Vue父子组件通信实现todolist的功能示例代码

    这篇文章主要给大家介绍了关于如何使用Vue父子组件通信实现todolist的功能的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • vue + element ui实现播放器功能的实例代码

    vue + element ui实现播放器功能的实例代码

    这篇文章主要介绍了vue + element ui实现播放器功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • vue中实现拖动调整左右两侧div的宽度的示例代码

    vue中实现拖动调整左右两侧div的宽度的示例代码

    这篇文章主要介绍了vue中实现拖动调整左右两侧div的宽度的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • vue.js中Vue-router 2.0基础实践教程

    vue.js中Vue-router 2.0基础实践教程

    这篇文章主要给大家介绍了关于vue.js中Vue-router 2.0基础实践的相关资料,其中包括vue-router 2.0的基础用法、动态路由匹配、嵌套路由、编程式路由、命名路由以及命名视图等相关知识,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-05-05
  • vue给组件传递不同的值方法

    vue给组件传递不同的值方法

    今天小编就为大家分享一篇vue给组件传递不同的值方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • 详解使用vue实现tab 切换操作

    详解使用vue实现tab 切换操作

    这篇文章主要介绍了详解使用vue实现tab操作,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • vue短信验证性能优化如何写入localstorage中

    vue短信验证性能优化如何写入localstorage中

    这篇文章主要介绍了vue短信验证性能优化写入localstorage中的方法,解决这个问题需要把时间都写到localstorage里面去,具体解决方法大家参考下本文
    2018-04-04

最新评论