本篇记录el-select一般搜索和远程搜索。
搜索基础用法
添加 filterable
关键字即可实现过滤(也可理解为组件自带的本地搜索),注意:只有添加了该关键词才能输入。multiple
用于实现多选,这里要注意的是加了multiple
之后,v-model 初始化必须是[],若使用 ‘’ 空字符串,在有弹窗的情况下,则会出现弹窗打开就执行了检验,出现了红色错误提示。
| <el-select v-model="roleForm.users" multiple filterable > <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" /> </el-select>
|
远程搜索
远程搜索添加remote
关键字,使用remote-method
添加搜索方法,默认传参为输入值,通过输入值进行搜索。
| <el-select v-model="roleForm.users" multiple filterable :loading="loading" remote :remote-method="remoteMethod" >
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const getDataUser = (data?: any) => { let params = data || {} getUsers(params) .then((res) => { const { data, data2, status, msg } = res if (status == 'ok') { state.userList = data } else { console.log(msg) } }) .catch((error) => { console.log(error) }) }
const loading = ref(false) const remoteMethod = async (query: string) => { if (query) { loading.value = true await getDataUser({ name: query, p: 1, pageSize: 10 }) loading.value = false } else { await getDataUser({ p: 1, pageSize: 10 }) } }
|
远程获取所有数据,前端实现本地搜索
default-first-option
属性表示在输入框按下回车,选择第一个匹配项,配合 filterable 使用;filter-method
用户过滤方法。
| <el-select v-model="roleForm.users" multiple filterable :filter-method="dataFilter" default-first-option > <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" /> </el-select>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const dataFilter = (val) => { if (val) { state.userList = state.userListAll.filter((item) => { if (item && !!~item.name.indexOf(val)) { return true } }) } else { getItems(1) } }
const getItems = (flag?: number) => { if (flag) { dataList.user.p = flag } let num = ~~dataList.user.p * ~~dataList.user.pageSize state.userList = state.userListAll.filter((item, index, arr) => { if (item) { return index < num } }) }
|
懒加载
如果初始化数据过多,可能会造成页面卡顿,这里尝试懒加载
| <el-select v-model="roleForm.users" multiple filterable v-loadmore="loadmore" > <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" /> </el-select>
|
| const vLoadmore = { mounted(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 <= this.clientHeight if (condition) { binding.value() } }) } }
const loadmore = () => { dataList.user.p++ getItems() }
|
运行时控制台报错了!
经过检查,发现是没有找到DOM,猜测方法执行时DOM渲染还没有完成。
因为这个组件是在 dialog 中初始化,猜测可能是 v-if 导致,先尝试将组件移除 dialog 来测试,结果还是报错。。。
再尝试在组件 onMounted
时给 loadmore
赋值,想法完全错误!指令不能这么写,必须写一个全局常量。自定义指令自身的 mounted
已经代表了在挂载的组件渲染完成之后执行。
接着打印 el 的值,发现 el-select 节点中没有 el-select-dropdown …查阅很多资料,大家好像都没遇到这个问题???
点击加载更多
没办法,手写一个点击加载更多!放在 el-option 下方:
| <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id" /> <div v-if="user.p * user.pageSize < userTotal" @click="loadmore" class="load-more"> 点击加载更多 </div>
|
防抖节流
防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
防抖debounce在连续的事件,只需触发一次回调的场景有:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流throttle在间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听
- 搜索框,搜索联想功能