我的下拉框数据有几万条直接卡爆了,浏览器崩溃那种!!!!

解决方案

做一个类似懒加载的功能缓冲,初始化时显示指定条数的下拉数据(指定条数必须要能使下拉框生成滚动条,不能太少),使用vue指令监听下拉框滚动条,当滚动到底部时再加载一部分,如此反复达到优化效果

参考博客:https://blog.csdn.net/qq_40251961/article/details/115318959

1、自定义监听滚动指令(el-select-loadmore.js)
import Vue from 'vue';
Vue.directive('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:
         * this.scrollHeight - this.scrollTop === this.clientHeight;
         *  - 1 兼容大部分浏览器 存在滚动到底部时this.scrollHeight - this.scrollTop 比 this.clientHeight 大(0,1)的情况
         */
        const condition = this.scrollHeight - this.scrollTop - 1 <= this.clientHeight;
        if (condition) binding.value();
      });
    }
  }
)

main.js中全局引入自定义指令

import './directives/el-select-loadmore'
2、组件中使用
<el-select
    v-model="form.value"
    filterable
    v-el-select-loadmore="loadMore"
    :filter-method="selectFilter"
    @visible-change="selectVisible"
    placeholder="请选择"
    :popper-append-to-body="false"
    popper-class="selectinfo"
>
    <el-option
        v-for="item in options_.slice(0, range)"
        :key="item.value"
        :label="item.label"
        :value="item.value"
    >
    </el-option>
</el-select>
data(){
	return{
		options:[],//总下拉数据
		options_:[],//过渡下拉数据
		range:100,//初始渲染条数基数
		filterTime:null,//自定义查询功能的节流定时器
	}
},
methods:{
	loadMore() {
		//传入指令的增加渲染条数方法
    	this.range += 50;
	},
	selectFilter(val) {
		// 自定义下拉查询方法
    	if (this.filterTime) {
        	clearTimeout(this.filterTime);
        	this.filterTime = null;
    	}
    	this.filterTime = setTimeout(() => {
       		if (val) {
            	let filterArr = this.options.filter(item => {
                	return item.label.toLowerCase().includes(val.toLowerCase());
            	});
            	this.options_ = filterArr;
        	} else {
            	this.options_ = this.options
        	}
    	}, 500);
	},
	selectVisible(v) {
		//下拉框显隐监听事件 控制渲染初始数据以及恢复总数据
    	this.range = 100;
    	if(!v) this.options_ = this.options;
	},
}
3、解决回显问题

思路:遍历所有数据,将对应回显的那一条数据放在第一条,这样就能总是满足回显的数据在第一次渲染的数据中

echo_select() {
  let l = this.options_ .length;
  for (let i = 0; i < l; i++) {
    if (this.options_ [i].value == this.form.value) {
      this.options_ .unshift(this.options_ [i])
      this.options_ .splice(i, 1)
      break;
    }
  }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐