需求:在项目中一个下拉框中需要展示6000条数据,并且这数据还在膨胀,对于接口来说查询这几千条数据响应时间是完全ok的,但是6000条数据对应6000个dom,前端渲染极其卡顿。
官方文档给到一些解决方案,其中虚拟滚动是最优解
但是由于项目问题nodejs版本不能提升支持不了这个解决方案,这里不做过多讲解,需要此方法的可以自行查找。
官方文档
这里由于项目使用的vue2版本较低,nodejs等都不能升级,无法引入新的依赖,等等各种问题的约束,结合我的项目自身问题,这里给到一些新的思路给有同样问题的朋友,方案是使用搜索框输入内容触发查询
<a-select
:placeholder="$t('请选择')"
show-search
:dropdownRender="menuNode => this.dropdownRender(menuNode)"
:filter-option="false"
:default-active-first-option="false"
:show-arrow="false"
:not-found-content="null"
:options="list"
@search="debouncedHandleSearch"
@change="handleSelectChange"
v-decorator="['xxx',validatorRules.xxx]"
>
</a-select>
<script>
import { debounce } from 'lodash';
export default {
//省略....
data: function () {
return {
selectedOption: '',
isLoading: false,
methods: {
debouncedHandleSearch: debounce(function handleSearch(value) {
this.searchValue = value;
this.loadyourList(value);
}, 300),
async loadyourList(searchValue) {
this.isLoading = true;
try {
this.yourList = [];
const response = await queryYouList({
pageNo: 1,
pageSize: 20000,
search: searchValue,
});
if (response.success) {
this.list = response.result.records.map(record => ({
value: record.id,
label: `${record.name} (${record.currency})`,
}));
// 检查 selectedOption 是否还在新的 list 中
const newOptionsValues = this.list.map(option => option.value);
if (!newOptionsValues.includes(this.selectedOption)) {
// 如果 selectedOption 不在新的列表中,重置或设置为第一个元素
this.selectedOption = this.list.length > 0 ? this.list[0].value : '';
}
} else {
console.log(response.message);
}
} finally {
this.isLoading = false;
}
},
handleSelectChange(value) {
console.log('Selected option:', value);
// 选项被选择后,重置 searchValue
this.searchValue = '';
},
dropdownRender(menuNode) {
if (this.isLoading) {
return <div style={{ padding: '10px', textAlign: 'center' }}>搜索中...</div>;
} else if (!this.searchValue) {
return <div style={{ padding: '10px', textAlign: 'center' }}>请输入关键词搜索</div>;
}
return menuNode;
},
效果如下