第6节:远程搜索弹窗(remote 模式),弹窗滚动加载分页
第6节远程搜索弹窗remote 模式弹窗滚动加载分页本节重点remote远程搜索输入关键词请求接口还有下拉弹窗滚动监听实现分页加载选项。区分【本地过滤 filterable】和【远程搜索 remote】。核心知识点remote开启远程搜索不再前端本地过滤需要自己在remote-method里面请求后端remote-method回调函数参数是用户输入的搜索关键词输入内容变化就触发loadingel-select 的 loading 属性请求接口时显示加载动画popper实例获取拿到弹窗 DOM监听 scroll 事件实现滚动到底加载更多⚠️ 坑点remote 模式下必须手动清空选项列表关键词变化要重置页码完整可测试代码template div classcontainer h4远程搜索下拉弹窗滚动分页加载/h4 el-select v-modelselectVal filterable remote :remote-methodhandleRemoteSearch :loadingloading placeholder输入关键词远程搜索 stylewidth:320px visible-changehandleVisibleChange el-option v-foritem in optionList :keyitem.id :labelitem.name :valueitem.id / /el-select p选中值{{ selectVal }}/p /div /template script setup import { ref } from vue const selectVal ref() const loading ref(false) const optionList ref([]) const page ref(1) const pageSize 5 const keyword ref() // popper DOM let popperDom null // 模拟接口请求 const fetchData async (searchKey, p) { // 模拟网络延迟 await new Promise(resolve setTimeout(resolve, 600)) // 模拟后端返回数据 const mockArr [] for(let i 1; i pageSize; i){ const id (p -1)*pageSize i mockArr.push({ id, name: ${searchKey || 全部} 选项-${id} }) } return mockArr } // 远程搜索触发 const handleRemoteSearch async (val) { keyword.value val page.value 1 // 关键词改变重置页码 loading.value true const res await fetchData(val, page.value) optionList.value res loading.value false } // 弹窗打开/关闭 const handleVisibleChange async (isOpen) { if(isOpen){ // 弹窗打开等待popper渲染完成获取弹窗滚动容器 setTimeout((){ popperDom document.querySelector(.el-select__popper .el-scrollbar__wrap) if(!popperDom) return // 绑定滚动事件 popperDom.addEventListener(scroll, handlePopperScroll) }, 100) }else{ // 弹窗关闭移除滚动监听防止多次绑定 if(popperDom){ popperDom.removeEventListener(scroll, handlePopperScroll) popperDom null } } } // 弹窗滚动事件 const handlePopperScroll async () { const { scrollTop, scrollHeight, clientHeight } popperDom // 判断滚动到底部预留20px容错 if(scrollTop clientHeight scrollHeight - 20 !loading.value){ loading.value true page.value 1 const res await fetchData(keyword.value, page.value) // 追加数据 optionList.value.push(...res) loading.value false } } /script style scoped .container { padding:20px; } /style测试步骤输入文字触发远程搜索看到 loading 加载动画列表刷新下拉弹窗滚动到底部自动加载下一页数据追加到弹窗列表修改搜索关键词页码重置列表重新请求第一页关闭弹窗滚动事件解绑避免多次监听内存泄漏业务坑总结remote 开启后原生前端过滤失效所有过滤逻辑交给后端visible-change 打开弹窗拿 popper DOM一定要加 setTimeout等弹窗 DOM 渲染完成弹窗关闭必须 removeEventListener否则多次打开弹窗会重复绑定滚动事件滚动加载要加 loading 锁防止短时间多次触发请求