el-select下拉数据过多,实现方法(纯前端懒加载)

995 阅读1分钟

**使用场景:**项目中有时候出现了下拉数据量过大,出现页面卡死问题

下拉懒加载方法

下拉懒加载, 当select滚动到底部时, 你再去请求一部分数据, 加入到当前数据中.

el-select

<el-select 
v-model="searchData.openDepartName"
 clearable placeholder="测试"
 filterable 
v-el-select-loadmore="openLoadMore(openRangeNumber)"
 :filter-method="openFilterMethod"
 @visible-change="openVisibleChange">
 <el-option 
v-for="item in openDepartList.slice(0, openRangeNumber)"
 :key="item"
 :value="item"
 :label="item"
>
</el-option>
</el-select>

先自定义指令:

directives:{ 
'el-select-loadmore':(el, binding) => {  
// 获取element-ui定义好的scroll盒子  
const SELECTWRAP_DOM = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap");
  if(SELECTWRAP_DOM){
   SELECTWRAP_DOM.addEventListener("scroll", function () {
    /** 
    * scrollHeight 获取元素内容高度(只读)
    * scrollTop 获取或者设置元素的偏移值,
    *  常用于:计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
     * clientHeight 读取元素的可见高度(只读)     * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
     * ele.scrollHeight - ele.scrollTop === ele.clientHeight;     */ 

   const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
    if (condition) binding.value(); 

  });
  }
 },
}

公共去抖函数

/** 
* 去抖函数
 * fn 待执行函数 
* wait 接收函数触发的时间区间 会在 
* immediate true wait时间段的开始阶段执行,false 末尾阶段执行
 */
debounce(fn, wait = 250, immediate = false) {
    let timeout, args, context, timestamp; 
    let later = function() {
  // wait指定的时间间隔期间不断调用debounce返回的函数 会不断更新timestamp,启动新的计时器,计算需要重新延时的时间  
    let last = new Date() - timestamp;  
    if (last < wait && last >= 0) timeout = setTimeout(later, wait - last);  
    else {   
        // wait >= last 执行 最近一次的调用   
        timeout = null;   
        if (!immediate) {    
            fn.apply(context, args);    
        context = args = null;   
        }  
    } 
    }; 
// 重复调用,重置timestamp 改变later内的last 
return function() {
  context = this;
  args = arguments;
  timestamp = new Date();
  let callNow = immediate && !timeout;
  if (!timeout) timeout = setTimeout(later, wait);
  // 在时间区间开头阶段立即执行
  if (callNow) {
   fn.apply(context, args);
   context = args = null;
  }
 };
},



或者 用有组件的 import debounce from 'lodash/debounce';  //引入

// 筛选方法
agentFilterMethod:debounce(function(filterVal){
 if(filterVal){ 
 let filterArr = this.agentResChannelList.filter((item)=>{
   return item.includes(filterVal)
  }) 
 this.agentChannelList = filterArr;
 }else{
  this.agentChannelList = this.agentResChannelList;
 }
},500),

// 下拉框出现时,调用过滤方法
agentVisibleChange(flag){
 if(flag){
  this.agentFilterMethod()
 }},
openLoadMore(n) { 
// n是默认初始展示的条数会在渲染的时候就可以获取,具体可以打log查看
 // elementui下拉超过7条才会出滚动条,如果初始不出滚动条无法触发loadMore方法
 return () => (this.openRangeNumber += 30); // 每次滚动到底部可以新增条数  可自定义
},