卡顿原因:DOM中数据过多,超过内存限制
解决思路
可以使用自定义指令,让el-select弹窗下拉到最底部时触发加载
自定义指令
创建select-load-more.js
import Vue from 'vue';
const selectLazyLoad = function (Vue) {
// el-select组件数据过多,使用翻页加载数据指令
Vue.directive('selectLazyLoad', {
bind(el, binding) {
const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap');
SELECTWRAP_DOM.addEventListener('scroll', function () {
const condition = this.scrollHeight - this.scrollTop - 1 <= this.clientHeight;
if (condition) {
console.log(condition);
binding.value();
}
});
}
});
};
if (window.Vue) {
Vue.use(selectLazyLoad);
}
export default selectLazyLoad;
在main.js中加入引入并使用自定义指令
import selectLazyLoad from '@/utils/select-load-more'; //引入自定义指令,懒加载el-select
Vue.use(selectLazyLoad);
使用自定义指令
template部分
<el-select v-model="value" @change="changSelect" placeholder="请选择作业类型" v-selectLazyLoad="() => loadMore()">
<el-option v-for="(item, index) in data.slice(0, pageSize)" :label="item.name" :key="index" :value="item.id"></el-option>
</el-select>
methods部分
/* 加载更多数据 */
loadMore() {
console.log('loadMore');
this.pageSize += 1;
},
这样即可实现el-select的懒加载,不过如果选择了还未加载的数据,回显的时候无法正常显示,所以需要处理下
回显处理
需要让后台将所选数据的id和name都回传给前端,再接收到列表数据后,将所选数据插入列表的首位
this.data.unshift({id: this.value, name: this.name});
这样就可以正常回显了,不过此时如果继续下拉到选中元素的位置,还是会出现两个都被选中的情况,如果想继续优化,就在loadMore方法里删除之前插入的数据即可
/* 加载更多数据 */
loadMore() {
/* 当下拉到选中元素后,删除之前插入的元素 */
let item = this.data[this.pageSize];
if (item.id == this.value) {
this.data.shift();
}
this.pageSize += 1;
},