在我们使用 Element 的 el-select 时,当下拉框的选项过多,我们一次性将所有选项都放入下拉框中会导致页面卡顿,每次点击下拉框都会出现白屏,我们可以用自定义指令实现下拉框的动态加载。
首先,在main.js文件中我们可以定义一个全局的指令
Vue.directive('loadmore', {
bind(el, binding) {
const dom = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
dom.addEventListener('scroll', function () {
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
if (condition) {
binding.value()
}
})
}
});
将动态加载的 el-select 封装成一个公共组件以便复用,起名为 MySelect.vue
<template>
<el-select
size="small"
multiple
v-bind="$attrs"
v-loadmore="loadProject"
collapse-tags
filterable
:clearable="clearableFlag"
:placeholder="placeholder"
:filter-method="handleFilter"
v-model="val"
@change="handleSearch"
@visible-change="handleVisibleProject"
>
<el-option
v-for="item in data.list"
:key="item.number"
:value="item.number"
:label="item.name"
>
{{ item.name }}
</el-option>
</el-select>
</template>
<script>
import _ from "lodash";
import { api } from "@/apis";
export default {
model: {
prop: "inputValue",
event: "change",
},
props: {
clearableFlag: {
type: Boolean,
default: false,
},
inputValue: {
type: [Array, String],
default: () => {
return [];
},
},
placeholder: {
type: String,
default: "请选择",
},
size: {
type: String,
default: "medium",
}
},
watch: {
inputValue(newValue, oldValue) {
this.val = newValue;
},
},
data() {
return {
val: "",
data: {
list: [],
total: 0,
},
// 请求参数
query: {
name: "",
currentPage: 1,
pageSize: 20,
},
isFristLoad: true,
};
},
methods: {
// 分页加载数据项
loadProject() {
const { pageSize, currentPage } = this.query;
if (pageSize * currentPage < this.data.total) {
this.query.currentPage++;
this.getList();
}
},
// 通过调用接口获取数据项
getList() {
// 下面是举例写法
// api.getList(this.query).then((res) => {
// if (res.data.success) {
// this.data.list = [...this.data.list, ...res.data.data.list];
// this.data.total = res.data.data.total;
// }
// });
},
// 筛选数据项
handleFilter: _.debounce(function (val) {
this.query.name = val;
this.query.currentPage = 1;
this.data.list = [];
this.data.total = 0;
this.getList();
}, 500),
// 隐藏显示下拉框
handleVisibleProject(tag) {
const { name } = this.query;
if (!tag) {
if (name !== "") {
this.handleFilter("");
}
} else if (this.isFristLoad) {
this.isFristLoad = false;
this.getList();
}
},
handleSearch(val) {
this.$emit("change", val);
},
},
};
</script>
在页面中引入我们刚刚封装的MySelect组件
<template>
<MySelect
placeholder="请输入"
v-model="keyword"
@change="handleSearch"
/>
<template>
import { MySelect } from "@/components/MySelect"
export default {
components: {
MySelect
},
data() {
return {
keyword: ""
}
},
methods: {
handleSearch() {}
}
}
快在自己的项目中试一试吧~