element 穿梭框效能優化的實現
目錄
- 背景
- 解決思路
- 新問題
- 進階
背景
穿梭框處理大資料量時,由於渲染的 DOM 節點過多,造成頁面卡頓的問題。
在儘量不改變元件原有邏輯的前提下,進行優化。
解決思路
懶載入 - InfiniteScroll 元件
先從 packages/transfer 中將原元件拷出(或者改原始碼重新打包維護私有庫使用)
將
v-infinite-scroll="pageDown" :infinite-scroll-immediate="false"
新增到
<el-checkbox-group v-show="!hasNoMatch && data.length > 0" v-model="checked" :sizehttp://www.cppcns.com="size" :class="{ 'is-filterable': filterable }" class="el-transfer-panel__list" v-infinite-scroll="pageDown" :infinite-scroll-immediate="false" > <el-checkbox class="el-transfer-panel__item" :label="item[keyProp]" :disabled="item[disabledProp]" :key="item[keyProp]" v-for="item in filteredData"> <option-content :option="item"></option-content> </el-checkbox> </el-checkbox-group>
在data中定義pageSize: 20 用來表示每頁資料個數showData: [] 僅用來展示使用,替換上述程式碼中實際需要操作的資料 filteredData
v-for="item in showData">
同時在watch中相應的處理
data (data) { const checked = []; this.showData = data.slice(0,this.pageSize); const filteredDataKeys = this.filteredData.map( (item) => item[this.keyProp] ); this.checked.forEach((item) => { if (filteredDataKeys.indexOf(item) > -1) { checked.pushhttp://www.cppcns.com(item); } }); this.checkChangeByUser = false; this.checked = checked; },filteredData (filteredData) { this.showData = filteredData.slice(0,this.pageSize); }
初始化展示數量隨意這裡取 20。
最後新增滾動到底部時呼叫的方法
pageDown () { const l = this.showDathttp://www.cppcns.coma.length; const totalLength = this.filteredData.length l < totalLength && (this.showData = this.filteredData.slice(0,l + this.pageSize > totalLength ? totalLength : l + this.pageSize)); },
往下滾動的時候 展示的資料長度增加 20(數量隨意),超出時展示最大長度。
由此基本解決大資料量操作卡頓的問題。由於展示和邏輯層分開,元件的所有操作邏輯無須修改,最小程度減少差異。
新問題
手動滾動到列表末端,再進行搜尋操作依然存在卡頓問題。
進階
在滾動過程中,實際上頂端的資料依舊無法看見,該資料不展示,對使用者體驗也沒有影響,
所以只需展示當前頁的 20 條資料。
我們為el-checkbox-group新增一個 ref=scrollContainer 以便操作滾動條,
在data中定義當前頁數 curIndex: 1
並對 pageDown 方法進行修改
pageDown () {
const totalLength = this.filteredData.length
if((this.curIndex*this.pageSize) < totalLength){
this.curIndex ++
const targetLength = this.curIndex * this.pageSize
coniILYMDst endPoint = targetLength > totalLength ? totalLength : targetLength
const startPoint = endPoint - this.pageSize > 0 ? endPoint - this.pageSize : 0
this.showData = this.filteredData.slice(startPoint,endPoint);
this.$refs.scrollContainer.$el.scrollTop = "1px" //滾動條到最上端,銜接下一頁,為 0 可能會觸發邊界問題
}
}
為此我們還需要新增向上翻頁的方法
InfiniteScroll 指令 只提供向下滾動,我們可以拓展該指令亦可自行新增上滑滾動監聽 mounted(){ this.$refs.scrollContainer.$el.addEventListener('scroll',this.pageUp) },beforeDestroy(){ this.$refs.scrollContainer.$el.removeEventListener('scroll',
註冊pageUp 方法
pageUp(e){ if(e.target.scrollTop ===0 && this.curIndex>1){ this.curIndex -- const endPoint = this.curIndex * this.pageSize const startPoint = (this.curIndex-1)* this.pageSize this.showData = this.filteredData.slice(startPoint,endPoint); const el = this.$refs.scrollContainer.$el el.scrollTop = el.scrollHeight - el.clientHeight - 1 // 滾動到最底部,銜接上一頁, -1 防止邊界問題。 } },
當進行資料操作的時候,頁面內容變化,滾動條也會隨之變化,為防止不能預知的翻頁,資料改變時,重置滾動條和當前頁碼。
initScroll(){ this.curIndex = 1 this.$refs.scrollContainer.$el.scrollTop = 0 },
同時地,在watch中相應時候執行 initScroll
data(){ ... this.initScroll() ... },filteredData (filteredData) { ... this.initScroll() }
至此大資料量的穿梭框,效能大為改善。
到此這篇關於element 穿梭框效能優化的實現的文章就介紹到這了,更多相關element 穿梭框效能優化內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!