需求背景
vue2+element-ui项目中,当el-select中数据量较大时(超出5000个dom节点),会导致页面加载和渲染卡顿、el-select下拉列表延迟展开。
在现在的el-select的基础上使用分页或者虚拟列表的形式去处理大量的下拉菜单,可以保证页面的正常渲染及el-select的正常回显。
需求分析
主要涉及几个点:
1、下拉菜单主体实现虚拟展示,保证渲染效率
2、展开和关闭时要保证已选中的选项在虚拟列表内,保证回显的是 label,而不是 value
3、select 清空时,虚拟列表回归到顶部
4、下拉菜单发生改变时,重新计算滚动条长度,并回归到顶部
5、支持搜索、多选、disabled、collapse-tags场景。
完整代码
安装虚拟列表插件vue-virtual-scroller,我这边安装的是^1.1.2版本。
封装组件virtualSelect.vue
<template>
<div>
<el-select
popper-class="virtualselect"
class="virtual-select-custom-style"
:value="defaultValue"
:filterable="field.props.filterable"
:filter-method="filterMethod"
:default-first-option="field.props.defaultFirstOption"
:popper-append-to-body="false"
:placeholder="$t(field.placeholder)"
:disabled="field.props.disabled"
:clearable="field.props.clearable"
:multiple="field.props.multiple"
:collapse-tags="field.props.collapseTags"
v-bind="$attrs"
@visible-change="visibleChange"
v-on="$listeners"
@clear="clearChange"
@focus="focusChange"
@change="selectChange"
>
<div v-if="selectArr.length > 0" class="scroll-list-box">
<RecycleScroller
ref="virtualList"
:style="'height:' + calcScrollHeight() + 'px;'"
class="scroller"
:items="selectArr"
:item-size="itemHeight"
:buffer="buffer"
:key-field="value"
>
<template #default="{ item }">
<el-option
:key="item[value]"
:label="item[label]"