vue+element:el-select下拉框数据过多时使用懒加载或远程搜索
最近遇到一个下拉框选项过多导致页面太卡甚至卡死的问题,搜了一下懒加载以及远程搜索方法,整理了一下:
1、el-select懒加载
el-select选择器里的数据通过后端返回得到,这里返回了将近两万条数据,点开选择器页面就特别卡,所以最好采用懒加载方法,具体使用如下:
控件部分:
<el-select
v-model="form"
placeholder=""
v-el-select-loadmore="loadmore" //懒加载方法
>
<el-option
v-for="item in dataItems"
:key="item.value"
:label="item.label"
:value="item.value"/>
</el-select>
数据部分:
form: {},
allData: [], //存放下拉框全部数据
dataItems: [], //下拉框显示的数据
pageData: { //懒加载相关参数,这里代表从第一条数据开始加载,一次加载二十项
pageIndex: 1,
pageSize: 20
},
方法部分:
directives: {
/** 下拉框懒加载 */
'el-select-loadmore': {
bind(el, binding) {
const SELECTWRAP_DOM = el.querySelector(
'.el-select-dropdown .el-select-dropdown__wrap'
);
SELECTWRAP_DOM.addEventListener('scroll', function() {
const condition =
this.scrollHeight - this.scrollTop <= this.clientHeight;
if (condition) {
binding.value();
}
});
}
}
},
methods: {
/** 下拉框懒加载 */
loadmore() {
this.pageData.pageIndex++;
this.getItems(this.pageData); //类似于分页查询
},
/** 一次加载二十条证券代码 */
getItems(value) {
let num = ~~this.pageData.pageIndex * ~~this.pageData.pageSize;
this.dataItems = this.allData.filter((item, index, arr) => {
return index < num; //这里默认allData已经取到了数据,就不把获取allData数据的方法放上来了
});
},
}
这样就实现了el-select下拉框数据的懒加载,注意:
如果和我一样下拉框里的选项(比如这里的allData)是动态变化的,在每次获取新的数据之后要把pageData里的数据还原,即在获取数据的方法里加上这两句:
this.pageData.pageIndex = 1;
this.pageData.pageSize = 20;
否则每次获取完新的数据之后只是从上一次加载到的地方开始加载,而不是重新从第一条开始每次加载二十条。
2、下拉框选项可搜索
由于我在实际使用的时候下拉框有接近两万条数据,出于需求考虑,不可能把所有数据全部加载一遍再选择,所以还需要有搜索功能,只要在上面代码的基础上加上:
控件部分,el-select改为:
<el-select
v-model="form"
placeholder=""
filterable //表示数据可搜索
:filter-method="dataFilter" //搜索的方法
default-first-option //在输入框按下回车,选择第一个匹配项,配合 filterable使用
v-el-select-loadmore="loadmore"
>
方法部分,添加dataFilter方法:
/** 下拉框搜索 */
dataFilter(val) {
if (val) { //val存在
this.dataItems = this.allData.filter((item) => {
if (!!~item.value.indexOf(val)) { //这里匹配的是选项的value,也可以改成label
return true
}
})
} else { //val为空时,还原数组
this.getItems(this.pageData);
}
},
3、远程搜索
但是在使用过程中发现上面的方法还是有点卡,所以再尝试了一下远程搜索的方法,在一开始不把所有选项展示出来,并且去掉懒加载,输入关键字之后再去匹配选项的value值,显示出匹配的选项:
控件部分,el-select改为:
<el-select
v-model="form"
clearable
filterable
remote //表示远程搜索
:remote-method="remoteMethod" //远程搜索方法
>
方法部分,添加remoteMethod方法:
remoteMethod(query) {
if (query !== '') {
setTimeout(() => {
this.dataItems = this.allData.filter(item => {
return item.value.toLowerCase() //这里同样是匹配选项的value
.indexOf(query.toLowerCase()) > -1;
});
}, 200);
} else {
this.dataItems = [];
}
},
尝试之后发现远程搜索会比懒加载+直接搜索渲染得更快一些,所以最终采用的是远程搜索方法