您好,登錄后才能下訂單哦!
這篇文章主要講解了“如何實(shí)現(xiàn)element穿梭框性能優(yōu)化”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何實(shí)現(xiàn)element穿梭框性能優(yōu)化”吧!
背景
解決思路
新問題
進(jìn)階
穿梭框處理大數(shù)據(jù)量時(shí),由于渲染的 DOM 節(jié)點(diǎn)過多,造成頁面卡頓的問題。
在盡量不改變組件原有邏輯的前提下,進(jìn)行優(yōu)化。
懶加載 - InfiniteScroll 組件
先從 packages/transfer 中將原組件拷出(或者改源碼重新打包維護(hù)私有庫使用)
將
v-infinite-scroll="pageDown" :infinite-scroll-immediate="false"
添加到
<el-checkbox-group v-show="!hasNoMatch && data.length > 0" v-model="checked" :size="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 用來表示每頁數(shù)據(jù)個(gè)數(shù)showData: [] 僅用來展示使用,替換上述代碼中實(shí)際需要操作的數(shù)據(jù) filteredData
v-for="item in showData">
同時(shí)在watch中相應(yīng)的處理
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.push(item); } }); this.checkChangeByUser = false; this.checked = checked; }, filteredData (filteredData) { this.showData = filteredData.slice(0, this.pageSize); }
初始化展示數(shù)量隨意這里取 20。
最后添加滾動(dòng)到底部時(shí)調(diào)用的方法
pageDown () { const l = this.showData.length; const totalLength = this.filteredData.length l < totalLength && (this.showData = this.filteredData.slice(0, l + this.pageSize > totalLength ? totalLength : l + this.pageSize)); },
往下滾動(dòng)的時(shí)候 展示的數(shù)據(jù)長度增加 20(數(shù)量隨意), 超出時(shí)展示最大長度。
由此基本解決大數(shù)據(jù)量操作卡頓的問題。由于展示和邏輯層分開,組件的所有操作邏輯無須修改,最小程度減少差異。
手動(dòng)滾動(dòng)到列表末端,再進(jìn)行搜索操作依然存在卡頓問題。
在滾動(dòng)過程中,實(shí)際上頂端的數(shù)據(jù)依舊無法看見,該數(shù)據(jù)不展示,對用戶體驗(yàn)也沒有影響,
所以只需展示當(dāng)前頁的 20 條數(shù)據(jù)。
我們?yōu)閑l-checkbox-group添加一個(gè) ref=scrollContainer 以便操作滾動(dòng)條,
在data中定義當(dāng)前頁數(shù) curIndex: 1
并對 pageDown 方法進(jìn)行修改
pageDown () { const totalLength = this.filteredData.length if((this.curIndex*this.pageSize) < totalLength){ this.curIndex ++ const targetLength = this.curIndex * this.pageSize const 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" //滾動(dòng)條到最上端,銜接下一頁,為 0 可能會(huì)觸發(fā)邊界問題 } }
為此我們還需要添加向上翻頁的方法
InfiniteScroll 指令 只提供向下滾動(dòng),我們可以拓展該指令亦可自行添加上滑滾動(dòng)監(jiān)聽 mounted(){ this.$refs.scrollContainer.$el.addEventListener('scroll', this.pageUp) }, beforeDestroy(){ this.$refs.scrollContainer.$el.removeEventListener('scroll', this.pageUp) },
注冊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 // 滾動(dòng)到最底部,銜接上一頁, -1 防止邊界問題。 } },
當(dāng)進(jìn)行數(shù)據(jù)操作的時(shí)候,頁面內(nèi)容變化,滾動(dòng)條也會(huì)隨之變化,為防止不能預(yù)知的翻頁,數(shù)據(jù)改變時(shí),重置滾動(dòng)條和當(dāng)前頁碼。
initScroll(){ this.curIndex = 1 this.$refs.scrollContainer.$el.scrollTop = 0 },
同時(shí)地,在watch中相應(yīng)時(shí)候執(zhí)行 initScroll
data(){ ... this.initScroll() ... }, filteredData (filteredData) { ... this.initScroll() }
至此大數(shù)據(jù)量的穿梭框,性能大為改善。
感謝各位的閱讀,以上就是“如何實(shí)現(xiàn)element穿梭框性能優(yōu)化”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何實(shí)現(xiàn)element穿梭框性能優(yōu)化這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。