时间:2022-11-19 10:51:57 | 栏目:vue | 点击:次
近期着手开发基于ElementUI的后台管理系统,偶然间发现「el-select」下拉选择时候遇到一个问题,当渲染下拉选项的「options」的数据量过多时「本项目中的数据条目已过万」,就会出现下拉选择器卡顿的情况,尤其是在模糊匹配过滤的情况下,显得十分的卡顿。初始化选择器的时候,也会点击无反应,有时候需要点击多次才可出现「dialog」弹窗(本次下拉筛选在弹窗中实现)。 翻阅多篇博客笔记之后,最终找到一个可以解决问题的方案,现将此次优化方案记录成为笔记,以便于日后遇到类似问题的时候便于查阅。
注:基于select的下拉筛选,通过自定义事件来实现模糊搜索匹配。
一共两种方案:
Vue组件实例
<template> <div class="app"> <el-dialog title="标题" :visible.sync="relatedOpen" :append-to-body="true" width="500px"> <el-row :gutter="16"> <el-col :span="20"> <el-select v-model="value" filterable clearable style="width:100%" placeholder="请选择" :loading="searchLoad" :filter-method="filterMethod" v-el-select-loadmore="loadMore(rangeNumber)" @visible-change="visibleChange" > <el-option v-for="item in options.slice(0, rangeNumber)" :key="item.key" :label="item.value" :value="item.key"></el-option> </el-select> </el-col> <el-col :span="4"> <el-button type="primary" @click="submit">确定</el-button> </el-col> </el-row> </el-dialog> </div> </template>
// 自定义指令 directives: { "el-select-loadmore": (el, binding) => { // 获取element UI定义好的scroll元素 const SELECTWRAP_ROM = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap"); if (SELECTWRAP_ROM) { // 添加scroll事件 SELECTWRAP_ROM.addEventListener("scroll", function() { // 判断滚动 const condition = this.scrollHeight - this.scrollTop <= this.clientHeight; condition && binding.value(); }); } } }
相应的数据函数
export default { data() { return { relatedOpen: false, options: [] /* 选择下拉框的值 */, courseList: [], rangeNumber: 10, searchLoad: false /* 下拉框的loading状态 */, value: "", timer: null }; }, created() { this.getOptions(); }, methods: { // 按需加载 loadMore(n) { return () => (this.rangeNumber += 5); }, // 过滤课件 filterMethod(query) { if (this.timer != null) clearTimeout(this.timer); !this.searchLoad && (this.searchLoad = true); this.timer = setTimeout(() => { this.options = !!query ? this.courseList.filter(el => el.value.toLowerCase().includes(query.toLowerCase())) : this.courseList; clearTimeout(this.timer); this.searchLoad = false; this.rangeNumber = 10; this.timer = null; }, 500); }, // 监听select下拉框的显示和隐藏 visibleChange(flag) { // 显示时初始化列表 flag && this.filterMethod(""); // 初始化默认值 this.rangeNumber = 10; }, // 获取选项 async getOptions() { await searchCourseware().then(res => { let list = res.data || []; // 默认展示的数据 this.options = list; // 原始数据 this.courseList = list; }); } } }
注:
换了新的工作环境,现开始着手做后台管理系统,或多或少会遇到各种各样的问题。一如即往,会在笔记中记录开发中遇到的问题。好记性不如烂笔头,希望现在埋下种子,等到来年秋天的时候会收获🍒果实。JY