vue大數(shù)據(jù)表格卡頓問題的完美解決方案
前言
vue渲染小數(shù)據(jù)挺快,大數(shù)據(jù)vue開始出現(xiàn)卡頓現(xiàn)象,本文講給大家詳細(xì)介紹關(guān)于vue大數(shù)據(jù)表格卡頓問題的解決方法
點(diǎn)我在線體驗(yàn)Demo(請(qǐng)用電腦查看)
親測蘋果電腦,chrome瀏覽器無卡頓現(xiàn)象,其它瀏覽器并未測試,如遇到卡頓請(qǐng)備注系統(tǒng)和瀏覽器,方便我后續(xù)優(yōu)化,謝謝
先看一下效果,一共1000 X 100 = 10W個(gè)單元格基本感受不到卡頓,而且每個(gè)單元格點(diǎn)擊可以編輯,支持固定頭和固定列
解決問題核心點(diǎn):橫向滾動(dòng)加載,豎向滾動(dòng)加載
項(xiàng)目背景
筆者最近在做廣告排期功能,需要進(jìn)行點(diǎn)位預(yù)占,大的合同可能需要對(duì)多個(gè)資源排期,周期可能到幾年這樣,然后我們的頁面交互是這樣
橫向每個(gè)月30個(gè)單元格,最多的3年,36個(gè)月,每行36*30=1080個(gè)單元格
豎向100個(gè)資源,總共約️10W個(gè)單元格,然后每個(gè)單元格里面會(huì)有一個(gè)輸入框,一個(gè)庫存總數(shù),所以總數(shù)是20W個(gè),內(nèi)網(wǎng)使用,接口請(qǐng)求根本不是問題,可以瀏覽器渲染就扛不住了接口回來之后會(huì)出現(xiàn)幾十秒的白屏,整個(gè)頁面處于卡死狀態(tài)
這還不算,加載出之后頁面操作也是非??ǎ瑒?dòng)延遲嚴(yán)重,頁面基本處于癱瘓狀態(tài)
之前的功能是基于jquery開發(fā)的,項(xiàng)目重構(gòu)用的vue,UI采用了ElementUI,ElmentUI中的表格在數(shù)據(jù)量較大是有嚴(yán)重的性能問題,最直接的表現(xiàn)就是白屏?xí)r間較長,而且會(huì)出現(xiàn)渲染錯(cuò)亂
所以就想著自己實(shí)現(xiàn)一個(gè)表格,解決卡頓問題
實(shí)現(xiàn)思路
表格拆分,動(dòng)態(tài)加載
表格橫向按月拆分,每個(gè)月份單獨(dú)一個(gè)table,月份table外層放一個(gè)占位div,根據(jù)橫向滾動(dòng)位置控制展示
豎向按資源拆分,同樣包裹一個(gè)占位div,按照滾動(dòng)位置動(dòng)態(tài)加載,始終保持dom數(shù)量上線
動(dòng)態(tài)編輯,按需生成編輯輸入框
不同的標(biāo)簽在瀏覽器渲染時(shí)性能是不一樣的,比如input這種標(biāo)簽就比span等標(biāo)簽重許多,所以不能滿屏input
方案就是點(diǎn)擊單元格展示輸入框,焦點(diǎn)丟失移除,此處的展示非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>
經(jīng)過如上優(yōu)化,完美解決表格卡頓問題,但是我并沒有封裝組件,原因如下
·插件封裝后會(huì)有很多限制,不能再用vue那種模板寫法,用json傳入數(shù)據(jù),自定義內(nèi)容不是很靈活
·可以根據(jù)自己的應(yīng)用場景自行修改拓展,代碼已經(jīng)很簡潔
·比較懶
如果你有類似需求可以試一下我這個(gè),也歡迎Star
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
vue中動(dòng)態(tài)設(shè)置meta標(biāo)簽和title標(biāo)簽的方法
這篇文章主要介紹了vue中動(dòng)態(tài)設(shè)置meta標(biāo)簽和title標(biāo)簽的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07vue與vue-i18n結(jié)合實(shí)現(xiàn)后臺(tái)數(shù)據(jù)的多語言切換方法
下面小編就為大家分享一篇vue與vue-i18n結(jié)合實(shí)現(xiàn)后臺(tái)數(shù)據(jù)的多語言切換方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03Vue+jquery實(shí)現(xiàn)表格指定列的文字收縮的示例代碼
這篇文章主要介紹了Vue+jquery實(shí)現(xiàn)表格指定列的文字收縮的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01解決vue中使用Axios調(diào)用接口時(shí)出現(xiàn)的ie數(shù)據(jù)處理問題
今天小編就為大家分享一篇解決vue中使用Axios調(diào)用接口時(shí)出現(xiàn)的ie數(shù)據(jù)處理問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08Vue Element前端應(yīng)用開發(fā)之圖標(biāo)的維護(hù)和使用
在Vue Element前端應(yīng)用中,圖標(biāo)是必不可少點(diǎn)綴界面的元素,Element界面組件里面提供了很多常見的圖標(biāo),因此考慮擴(kuò)展更多圖標(biāo),引入了vue-awesome組件,它利用了Font Awesome的內(nèi)置圖標(biāo),實(shí)現(xiàn)了更多圖標(biāo)的整合,可以在項(xiàng)目中使用更多的圖標(biāo)元素了2021-05-05基于vue組件實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了基于vue組件實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11