element-ui中select下拉框加載大數(shù)據(jù)渲染優(yōu)化方式
現(xiàn)在的前端項(xiàng)目中對于element-ui的使用幾乎已經(jīng)是一個(gè)常規(guī)動作了,但是組件庫中的ui組件不一定都能滿足實(shí)際場景的需求,比如今天要講的select下拉框選擇組件。
我們公司是做證券行業(yè)基礎(chǔ)設(shè)施的,股票和證券的數(shù)量動不動就是上千,當(dāng)使用select渲染的時(shí)候就會很有壓力,我司大致3000條數(shù)據(jù),全部渲染出來大致需要4s左右,并且多選模式時(shí),選中和反選時(shí)會明顯感覺卡頓,這在體驗(yàn)上是覺得不能接受的,所以就開始了優(yōu)化歷程。
方案一
把下拉多選功能做成彈框表格多選
可行性:表格設(shè)置selection屬性,翻頁功能可以解決大數(shù)據(jù)問題
實(shí)際情況:需要展示的字段只要2個(gè)即可,對于表格來說太少,顯得太空;產(chǎn)品也不同意
棄之~~
方案二
利用select的遠(yuǎn)程搜索功能,初始化只加載指定數(shù)量數(shù)據(jù),其它數(shù)據(jù)通過搜索功能查詢
可行性:能滿足大數(shù)據(jù)需求,只是體驗(yàn)上打了點(diǎn)折扣,后臺也能支持
實(shí)際情況:產(chǎn)品能接受
暫時(shí)只想到了這兩種方案,和后臺商量了一下,具有可實(shí)施性,于是采用該方案。
方案分析
1.問題的根源是一次性渲染太多數(shù)據(jù)導(dǎo)致卡頓,那么第一次加載的數(shù)據(jù)就需要找到一個(gè)既能最大限度滿足業(yè)務(wù)需求,又能無感加載的臨界值,最終我選了300條
2.輸入中文搜索時(shí)傳遞queryName作為模糊查詢條件
3.如果通過搜索條件勾選了300條以后的數(shù)據(jù),失去焦點(diǎn),重新獲取焦點(diǎn)時(shí),需要將已勾選的數(shù)據(jù)放到300條數(shù)據(jù)的最前面,方便用戶查看和反選,此時(shí)需要用已選擇數(shù)據(jù)的id結(jié)合作為查詢條件queryIds
4.編輯時(shí)后臺只會返回新增時(shí)添加項(xiàng)對應(yīng)的id集合,要正確顯示對應(yīng)的name值,需將id集合作為參數(shù)請求列表數(shù)據(jù),如果不加參數(shù)默認(rèn)返回前300條數(shù)據(jù),如果id里有300之后的數(shù)據(jù),則不會正確展示。第一次新增時(shí)無需傳參。
基于以上分析,開始寫代碼
<!-- -->
<template>
<div class="container">
<el-select
v-model="selectVal"
filterable
multiple
clearable
collapse-tags
remote
reserve-keyword
:remote-method='remoteMethod'
@focus="focus"
>
<el-option v-for="(item, index) in options" :key="index"
:label='item.label'
:value='item.id'
>
</el-option>
</el-select>
</div>
</template>
<script>
export default {
data () {
return {
selectVal: [],
options: [
// {
// id: 1,
// label: 'one'
// },
// {
// id: 1,
// label: 'one'
// }
]
};
},
mounted() {
this.getData()
},
methods: {
getData(queryName, queryIds) {
this.$api('api/get', {
queryName: queryName || '',
queryIds: queryIds || '',
}).then(res => {
this.options = res.data
}).catch(err => {
// dosomething
})
},
remoteMethod(query) {
// 輸入文字模糊搜索,覆蓋舊數(shù)據(jù)
this.getData(query)
},
focus(event) {
if(!event.sourceCapabilities) return // 如果是勾選或反選下拉選項(xiàng)
if(!event.target.value) { // 輸入框沒有搜索條件時(shí)觸發(fā)
this.getData(undefined, this.selectVal)
}
}
}
}
</script>
<style lang='scss' scoped>
</style>focus函數(shù)是用來解決問題3或者編輯時(shí)獲取焦點(diǎn)的,但是element-ui的select中點(diǎn)擊選項(xiàng)時(shí)會觸發(fā)focus方法,對比了正真的focus和點(diǎn)擊,發(fā)現(xiàn)只有event.sourceCapabilities值可以區(qū)分,便用于區(qū)分這兩個(gè)事件;
如果有搜索條件時(shí)也不觸發(fā)id搜索,只觸發(fā)默認(rèn)的remoteMethod即可
新增數(shù)據(jù)的時(shí)候已經(jīng)可以用了,編輯的時(shí)候就會遇到問題4,此時(shí)需要用返回的id集合作為參數(shù)請求下拉數(shù)據(jù),以正確展示已選數(shù)據(jù)
data () {
return {
selectVal: [],
options: [
// {
// id: 1,
// label: 'one'
// },
// {
// id: 1,
// label: 'one'
// }
],
type: 'edit'
};
},
mounted() {
this.initDialog()
},
methods: {
initDialog() {
this.getEditInfo(this.type).then(ids => {
this.selectVal = ids
this.getData(undefined, ids)
})
},
getEditInfo(type) {
return new Promise((resolve, reject) => {
if(type === 'edit') { // 編輯
this.$api('api/getInfo', {}).then(res => {
let ids = res.data
resolve(ids)
}).catch(err => {
// dosomething
})
}else {
resolve()
}
})
},
getData(queryName, queryIds) {
this.$api('api/getOptions', {
queryName: queryName || '',
queryIds: queryIds || '',
}).then(res => {
this.options = res.data
}).catch(err => {
// dosomething
})
},
remoteMethod(query) {
// 輸入文字模糊搜索,覆蓋舊數(shù)據(jù)
this.getData(query)
},
focus(event) {
if(!event.sourceCapabilities) return // 如果是勾選或反選下拉選項(xiàng)
if(!event.target.value) { // 輸入框沒有搜索條件時(shí)觸發(fā)
this.getData(undefined, this.selectVal)
}
}
}這樣就可以滿足大數(shù)據(jù)加載的需求了
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 如何解決element-ui中select下拉框popper超出彈框問題
- 去除element-ui下拉框的下拉箭頭的實(shí)現(xiàn)
- 基于element-ui中el-select下拉框選項(xiàng)過多的優(yōu)化方案
- 關(guān)于element-ui?select?下拉框位置錯(cuò)亂問題解決
- element-ui+vue-treeselect下拉框的校驗(yàn)過程
- 解決element-ui的下拉框有值卻無法選中的情況
- Vue + Element-ui的下拉框el-select獲取額外參數(shù)詳解
- 在element-ui的select下拉框加上滾動加載
- 使用Vant完成DatetimePicker 日期的選擇器操作
- 如何修改element-ui日期下拉框datetimePicker的背景色樣式
相關(guān)文章
vue2.6.10+vite2開啟template模板動態(tài)編譯的過程
這篇文章主要介紹了vue2.6.10+vite2開啟template模板動態(tài)編譯,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Vue自定義指令實(shí)現(xiàn)對數(shù)字進(jìn)行千分位分隔
對數(shù)字進(jìn)行千分位分隔后展示應(yīng)該是大部分同學(xué)都做過的功能了吧,常規(guī)的做法通常是編寫一個(gè)工具函數(shù)來對數(shù)據(jù)進(jìn)行轉(zhuǎn)換,那么我們可不可以通過vue指令來實(shí)現(xiàn)這一功能呢,下面我們就來探索一下呢2024-02-02
淺談Vue.js中如何實(shí)現(xiàn)自定義下拉菜單指令
這篇文章主要介紹了淺談Vue.js中如何實(shí)現(xiàn)自定義下拉菜單指令,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01
vue 項(xiàng)目中常用的 2 個(gè) Ajax 庫及簡單使用示例
Ajax是一種在不重新加載整個(gè)頁面的情況下,通過 JavaScript 與服務(wù)器進(jìn)行異步通信的技術(shù),這篇文章主要介紹了vue項(xiàng)目中常用的2 個(gè) Ajax庫,需要的朋友可以參考下2025-06-06
結(jié)合el-upload組件實(shí)現(xiàn)大文件分片上傳功能
Element UI的el-upload上傳組件相信各位小伙伴都已經(jīng)非常熟悉,最近接了一個(gè)新需求,要求在el-upload組件基礎(chǔ)上實(shí)現(xiàn)分片上傳功能,即小于等于5M文件正常上傳,大于5M文件切成5M每片上傳,那么這個(gè)功能怎么實(shí)現(xiàn)呢?一起看看吧2022-09-09
Vue 項(xiàng)目部署到服務(wù)器的問題解決方法
本篇文章主要介紹了Vue 項(xiàng)目部署到服務(wù)器的問題解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12

