图示效果
注:基于select的下拉筛选,通过自定义事件来实现模糊搜索匹配。
一共两种方案:
- 一是获取所有数据,通过输入的关键字自己对获取的数据进行过滤处理;
- 二是通过输入的关键字来动态请求后台接口,通过接口返回的数据来动态渲染下拉选项;
代码实现
<template> <div class="app"> <el-dialog title="标题" :visible.sync="relatedOpen" :append-to-body="true" width="500px"> <el-row :gutter="16"> <el-col :span="20"> <el-select v-model="value" filterable clearable style="width:100%" placeholder="请选择" :loading="searchLoad" :filter-method="filterMethod" v-el-select-loadmore="loadMore(rangeNumber)" @visible-change="visibleChange" > <el-option v-for="item in options.slice(0, rangeNumber)" :key="item.key" :label="item.value" :value="item.key"></el-option> </el-select> </el-col> <el-col :span="4"> <el-button type="primary" @click="submit">确定</el-button> </el-col> </el-row> </el-dialog> </div> </template>
|
● 「v-el-select-loadmore」为自定义指令封装的数据加载指令,是为了解决和优化elementUI下拉选择器加载数据过多出现卡顿问题的。
● 「filter-method」是下拉选择器的一个自定义属性,可以监听输入的变量,从而依据变量来实现数据的动态获取;
自定义指令
directives: { "el-select-loadmore": (el, binding) => { const SELECTWRAP_ROM = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap"); if (SELECTWRAP_ROM) { SELECTWRAP_ROM.addEventListener("scroll", function() { const condition = this.scrollHeight - this.scrollTop <= this.clientHeight; condition && binding.value(); }); } }
|
注册指令(main.js引入文件)
import loadmore from '...../el-select/loadmore'
Vue.directive('el-select-loadmore', loadmore)
|
相应的数据函数
export default { data() { return { relatedOpen: false, options: [] , courseList: [], rangeNumber: 10, searchLoad: false , value: "", timer: null }; }, created() { this.getOptions(); }, methods: { loadMore(n) { return () => (this.rangeNumber += 5); }, filterMethod(query) { if (this.timer != null) clearTimeout(this.timer); !this.searchLoad && (this.searchLoad = true); this.timer = setTimeout(() => { this.options = !!query ? this.courseList.filter(el => el.value.toLowerCase().includes(query.toLowerCase())) : this.courseList; clearTimeout(this.timer); this.searchLoad = false; this.rangeNumber = 10; this.timer = null; }, 500); }, visibleChange(flag) { flag && this.filterMethod(""); this.rangeNumber = 10; }, async getOptions() { await searchCourseware().then(res => { let list = res.data || []; this.options = list; this.courseList = list; }); } } }
|
注:
● 定时器作用是防止输入筛选的关键字太过频繁,从而造成数据响应不及时;因为本次是一次性获取了全部的数据,所以这里只是用做渲染加载数据;
● 选择器的事件函数主要是用来初始化“获取焦点”和“失去焦点”时处理默认展示数据用的,若是获取的网络请求,此处需要做“函数截流”处理;目的是减少接口请求次数。