下拉数据几千条,直接使用防抖节流操作,先封装一个el-select的组件,默认下拉展示10条数据,划到最后一条再多加载10条,一次内推
定义父子关系,获取所有数据后传入封装el-select组件
父组件:periodslistend:通过接口获取到所有下拉的数据,periodNum2:双向绑定的数据,可以设置默认值,periodslist为了区分俩个下拉选择器的开始和结束的数据,结束日期之前的数据在开始日期之前都是禁用状态。flag:判定开始还是结束
// 引用封装的下拉框组件
import loadselect from "../component/select";
<loadselect
:compareopt="periodslist"
:compare="periodNum1"
:resOptions="periodslist"
:list="periodslistend"
:flag="'s'"
@parentHandler="choose_start1"
></loadselect>
<!-- 封装一个防抖节流的element下拉框组件 -->
//子组件接受父组件传值。
<el-select
v-model="compares"
:placeholder="$t('language.general.select')"
//可搜索
filterable
//自定义搜索方法
:filter-method="filterMethod"
@visible-change="visibleChange"
//自定义指令
v-el-select-loadmore="loadMore(rangeNumber)"
//下拉选择改变事件
@change="changefunc"
//失去焦点事件
@focus="update"
>
//把获取到的所有数据赋值给compareopt,rangeNumber限制10条
<el-option
v-for="item in compareopt.slice(0, rangeNumber)"
:key="item.period_num"
:label="item.period_num + ': ' + item.date + ' ' + item.time"
:value="item.value"
:disabled="flag=='s'?item.isdis:flag=='e'?item.disabled:false"
></el-option>
</el-select>
//script
import { _debounce } from "../../../static/utils";
export default {
name: "loadselect",
// 接收子组件传来的值
props: {
compareopt: {
type: Array,
default: [],
},
compare: [String, Number],
resOptions: {
type: Array,
default: [],
},
list: {
type: Array,
default: [],
},
flag: {
type: String,
default: "s",
},
},
data() {
return {
// 测试下拉框内容过多卡顿的问题2021.1.8
rangeNumber: 10,
};
},
computed: {
compares: {
get() {
var that = this;
return that.compare;
},
set(val) {
return val;
},
},
},
mounted() {
console.log(this.compare);
},
watch: {
compare(newval, oldval) {
var that = this;
that.compares=newval
// 区分开始周期和结束周期
// 开始周期
if (that.flag == "s") {
for (var i = 0; i < that.list.length; i++) {
if (that.list[i].value < newval) {
that.list[i].disabled = true;
} else {
that.list[i].disabled = false;
}
}
} else if (that.flag == "e") {
for (var i = 0; i < that.list.length; i++) {
if (that.list[i].value > newval) {
that.list[i].isdis = true;
} else {
that.list[i].isdis = false;
}
}
}
},
},
methods: {
// 获取焦点就强制刷新一次数据,不然会有延迟
update() {
this.$forceUpdate();
},
// 2020.1.8测试下拉框内容过多卡顿的问题
loadMore(n) {
// n是默认初始展示的条数会在渲染的时候就可以获取,具体可以打log查看
// elementui下拉超过7条才会出滚动条,如果初始不出滚动条无法触发loadMore方法
return () => (this.rangeNumber += 5); // 每次滚动到底部可以新增条数 可自定义
},
// 筛选方法
filterMethod: _debounce(function (filterVal) {
console.log(filterVal,'筛选数组');
if (filterVal) {
//---20210916-add-zjl---
//debugger;
//---添加属性值label判断,无label时通过value过滤
var is_label = false;
var oneObj = (this.resOptions.length > 0) ? this.resOptions[0] : {};
if (oneObj != {}) {
for (var key in oneObj) {
if (key == "label") {
is_label = true;
break
}
}
}
//---20210916-add-zjl---
let filterArr = this.resOptions.filter((item) => {
if(!is_label) return (item.value+"").toLowerCase().includes(filterVal.toLowerCase());
return item.label.toLowerCase().includes(filterVal.toLowerCase());
});
this.compareopt = filterArr;
} else {
this.compareopt = this.resOptions;
console.log(this.compareopt,'筛选数组元素赋值');
}
}, 500),
// 下拉框出现时,调用过滤方法
visibleChange(flag) {
if (flag) {
this.filterMethod();
}
},
changefunc(val) {
var that = this;
that.$forceUpdate();
this.$emit("parentHandler", val);
},
},
// 自定义指令
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 - Math.ceil(this.scrollTop) <= this.clientHeight;
if (condition) binding.value();
});
}
},
},
};
节流功能实现
function _debounce(fn, delay = 300) {
var timer = null;
return function () {
var _this = this;
var args = arguments;
if (timer) clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(_this, args);
}, delay);
};
}
export {
_debounce
}
文章到此结束,希望对你有所帮助