尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Snowy 中 XnPageSelect 分页下拉选择器:基于 Ant Design Vue Select 的懒加载搜索封装实战
后端前端认证鉴权应用安全【免费下载链接】Snowy国内首个国密前后分离快速开发平台《免费商用》基于开源技术栈精心打造融合Vue3AntDesignVue4Vite5SpringBoot3MpHuToolSa-Token。平台内置国密加解密功能保障前后端数据传输安全全面支持国产化环境适配多种机型、中间件及数据库。特别推荐插件提供工作流、多租户、多数据源、即时通讯等高级插件灵活接入让您的项目开发如虎添翼。项目地址https://gitcode.com/xiaonuobase/Snowy点击查看免费下载导读XnPageSelect 是 Snowy 快速开发平台snowy-admin-web内置的一款分页下拉选择器组件它在 Ant Design Vue 官方a-select的基础之上封装了调用后端分页接口、懒加载查询下拉数据的能力并在此基础上进一步支持输入关键词触发后端模糊搜索。本文以组件自带文档README.md为核心结合组件源码index.vue与仓库内真实页面用例完整讲解它的引入方式、属性与内置方法、数据契约、联动刷新、编辑回显以及后端配套接口的实现原理帮助你直接在新表单页中复用这套数据量大也能流畅选择的通用方案。一、组件定位为什么需要分页下拉选择器在实际后台管理系统中下拉选择最常见的问题不是用法复杂而是数据量太大组织、职位、客户、用户动辄成千上万条若一次性把全量数据塞进a-select的options既拖慢接口响应又让下拉面板渲染卡顿搜索也无法在服务端进行。XnPageSelect 解决的就是这个痛点基础的使用方式与 API 与官方版Select基本一致在其基础上封装了加载数据的方法——调用后端分页接口以懒加载的效果查询下拉数据同时支持搜索框搜索搜索时直接调用后端数据搜索接口而非前端本地过滤。也就是说组件的交互形态仍是标准下拉框但数据来源从一次性全量数组变成了分页接口按需拉取滚动到底部自动加载下一页搜索词实时传给后端做模糊匹配。这一点从组件源码可得到印证index.vue中渲染的仍是a-selectv-ifprops.showSearch时带show-search的搜索版否则为普通版数据通过:optionsoptions注入options则完全由分页接口的返回结果驱动。二、快速上手引入组件与第一个示例2.1 引入方式组件位于仓库路径 snowy-admin-web/src/components/XnPageSelect/在需要使用它的页面中直接引入即可import XnPageSelect from /components/XnPageSelect/2.2 示例一基础使用含组织-职位联动组件自带文档给出的第一个示例是选择组织 选择职位的表单场景组织使用a-tree-select树选择器职位使用xn-page-select分页下拉选择器当组织变化时通过组件实例的onPage({ orgId })重新请求职位数据实现联动筛选。template a-col :span8 a-form-item label选择组织 nameorgId a-tree-select v-model:valueformData.orgId stylewidth: 100% :dropdown-style{ maxHeight: 400px, overflow: auto } placeholder请选择组织 allow-clear tree-default-expand-all :tree-datatreeData :tree-default-expanded-keystreeDefaultExpandedKeys :field-namestreeFieldNames changeselePositionData(formData.orgId, 0) /a-tree-select /a-form-item /a-col a-col :span8 a-form-item label选择职位 namepositionId xn-page-select refxnPositionPageSelectRef v-model:valueformData.positionId placeholder请选择职位 allow-clear :page-functionselectApiFunction.positionSelector / /a-form-item /a-col /template script setup import XnPageSelect from /components/XnPageSelect/ import bizUserApi from /api/biz/bizUserApi // 表单数据 const formData ref({}) const xnPositionPageSelectRef ref() const treeFieldNames { children: children, title: name, key: id } // 机构选择后查询对应的职位 const selePositionData (orgId, type) { if (orgId) { const xnPositionPageSelectParam { orgId: orgId } xnPositionPageSelectRef.value.onPage(xnPositionPageSelectParam) xnUserPageSelectRef.value.onPage() // 此类型代表选择的时候重置后面的职位 if (type 0) { formData.value.positionId undefined formData.value.directorId undefined } } else { formData.value.positionId undefined formData.value.directorId undefined } } // 传递选择组件需要的API const selectApiFunction { positionSelector: (param) { return bizUserApi.userPositionSelector(param).then((data) { return Promise.resolve(data) }) }, } /script这个示例覆盖了组件最核心的使用范式可以拆解为三点v-model:value双向绑定选中值与a-select完全一致refonPage主动触发加载页面挂载或条件变化时通过ref拿到组件实例并调用onPage(param)请求第一页数据page-function传入分页接口函数组件并不关心接口的具体实现只要求传入一个接收分页参数、返回 Promise的函数。仓库中的真实页面也沿用了完全相同的写法可对照查看snowy-admin-web/src/views/sys/user/form.vue系统用户编辑页与 snowy-admin-web/src/views/biz/user/form.vue业务人员编辑页两者都在选择职位、选择主管等表单项中使用了xn-page-select。三、内置属性详解除去a-select自带属性外XnPageSelect 还额外提供以下属性属性说明类型默认值pageFunction分页函数必须为Promise对象必须绑定Promise-pageSize分页条数Number10showSearch配置是否可搜索BooleanfalsesearchKeyName搜索字段属性名String对照源码index.vue 的defineProps可以进一步确认各属性的行为与约束pageFunctiontype: Function无默认值必填。组件源码中onPage的第一步就是判断if (props.pageFunction)未传入时直接跳过请求逻辑下拉将没有任何数据。它必须是返回Promise的分页函数调用时组件会向其传入形如{ current, size, ...额外参数 }的分页查询参数。pageSizetype: Number默认10每页条数。onPage内部会通过{ ...param, size: props.pageSize }注入到请求参数中默认每次加载 10 条。showSearchtype: Boolean默认false是否开启搜索。开启后组件渲染带show-search的a-select用户输入关键词会触发后端搜索关闭时filterOption会被设为!props.showSearch即本地过滤也被关闭完全依赖服务端。searchKeyNametype: String默认搜索字段的属性名。用户输入的关键词会以{ [searchKeyName]: 关键词 }的形式拼进请求参数发给后端。留空时输入关键词不会触发请求。此外组件还透传了placeholder默认请选择、allowClear默认false、disabled默认false等常用属性a-select的其余属性也均可按官方用法直接使用。四、支持搜索框搜索调用后端数据搜索4.1 示例二客户名称选择器当数据量大、需要按名称精确查找时开启服务端搜索模式即可。组件自带文档的第二个示例展示了完整用法template xn-page-select refxnCustomerPageSelectRef v-model:valuesearchFormState.customerInfoId placeholder请选择客户名称 searchKeyNamecustomerName changetableRef.refresh(true); allow-clear show-search :page-functionselectApiFunction.customerSelector / /template script setup import XnPageSelect from /components/XnPageSelect/ import customerInfoApi from /api/eden/customerInfoApi; const xnCustomerPageSelectRef ref(); const searchFormState ref(); nextTick(() { xnCustomerPageSelectRef.value.onPage({current: 1}); }); const selectApiFunction { customerSelector: (param) { return customerInfoApi.customerPage(Object.assign(param, {envFlag: searchFormState.value.envFlag})).then((data) { if (data.records){ data.records data.records.map((item) { return { name: item.customerName, id: item.customerInfoId, }; }); } return Promise.resolve(data) }) } } /script与示例一相比这里多了三个关键点show-search开启搜索下拉框出现输入框searchKeyNamecustomerName指定搜索字段用户输入的内容会作为customerName参数传给后端由后端执行模糊查询在page-function中做字段映射后端返回的客户记录字段是customerName/customerInfoId而组件约定下拉数据使用name/id因此在then中统一map成{ name, id }结构再返回。同时nextTick(() { ... onPage({ current: 1 }) })保证了组件挂载完成后立即加载第一页数据让下拉打开即有内容。搜索模式下用户还可通过change感知选中变化例如在示例中触发tableRef.refresh(true)刷新关联表格。文档配套的演示动图分页下拉查询展示.gif直观展示了下拉懒加载 关键词服务端搜索的交互效果。4.2 搜索的源码链路从组件源码看搜索触发链路非常清晰用户输入时触发handleSearch(searchValue)它构造_params { current: 1 }当searchKeyName非空时写入_params[searchKeyName] searchValue随后调用onPage({ ...initParams.value, ..._params })重新请求第一页搜索时强制回到第 1 页避免停留在旧页面上拼出错误的翻页结果搜索过程同样由pageFunction转发给后端实现的是服务端模糊查询后端侧一般为like匹配详见后文后端实现部分。五、内置方法onPage 与联动刷新方法说明参数类型参数示例onPage请求分页数据Object{current: 1}onPage(param)是组件通过defineExpose暴露给父组件的唯一内置方法源码中defineExpose({ onPage })作用是以指定参数请求分页数据并刷新下拉列表。调用时组件会合并已有参数与本次传入参数并注入size: props.pageSize强制重置current 1确保从第一页开始加载设置spinning加载态调用pageFunction请求成功后更新当前页码、记录total总数、把data.records写入options随后执行回显逻辑。onPage最常见的两个应用场景页面/弹窗打开时初始化如示例二中的nextTick(() ref.onPage({ current: 1 }))确保组件挂载后即有数据联动刷新如示例一中组织树变化后调用onPage({ orgId })把组织 ID 作为过滤条件重新拉取该组织下的职位列表。在仓库的真实表单 snowy-admin-web/src/views/sys/user/form.vue 中联动逻辑写得更为紧凑selePositionData里通过xnPositionPageSelectRef.value.onPage({ orgId })刷新职位、xnUserPageSelectRef.value.onPage()刷新主管并在切换组织时把positionId、directorId重置为undefined避免职位/主管属于旧组织的数据错位。业务侧的同名实现可参见 snowy-admin-web/src/views/biz/user/form.vue。六、数据契约分页函数返回格式与字段重映射6.1 records 约定格式组件对分页函数返回的数据格式有明确约定这是使用时最容易踩坑的地方分页函数返回的 Promise 对象的 data 数据是分页格式的数据data.records格式如下{ name: name, id: id }其中id最终是你的valuename是你的显示名称。也就是说组件通过selectFieldNames { label: name, value: id }见 index.vue 源码把每条记录的name当作下拉展示文案、id当作选中值。同时分页返回体中必须包含total总条数用于判断是否还有下一页与current当前页码用于滚动加载时累加页码。6.2 字段名不匹配时如何重封装如果后端返回的data.records字段命名不符合约定例如客户模块返回的是customerName、customerInfoId可以像示例二那样在page-function里重新封装一层const selectApiFunction { customerSelector: (param) { return customerInfoApi.customerPage(Object.assign(param, {envFlag: searchFormState.value.envFlag})).then((data) { if (data.records){ data.records data.records.map((item) { return { name: item.customerName, id: item.customerInfoId, }; }); } return Promise.resolve(data) }) } }重封装时注意保留records数组之外的分页元信息total、current因为组件的滚动分页逻辑依赖它们handlePopupScroll在滚动触底时判断options.length total才继续请求下一页handlePagination则用initParams.current 1计算下一页页码并把新数据与旧数据按id去重合并源码中通过reduce以id为 key 完成去重避免翻页边界出现重复项。七、编辑回显echoFunction 与选中值回填组件自带的 README 主要聚焦查询选择而从 index.vue 的源码可以看到组件还内置了一个更实用的能力——echoFunction回显函数当表单进入编辑态、v-model:value已有选中值但当前下拉列表里没有该记录时例如职位/主管数据被分页截断组件会自动调用echoFunction({ idList: [modelValue] })按 ID 反查记录并将结果unshift到options最前面保证编辑时选中项能正确回显为名称。该属性未在文档表格中单独列出但从代码结构看属于组件稳定提供的能力仓库中的真实用例也大量使用例如 snowy-admin-web/src/views/sys/user/form.vueconst selectApiFunction { positionSelector: (param) userApi.userPositionSelector(param), userSelector: (param) userApi.userSelector(param), echoPosition: (param) userCenterApi.userCenterGetPositionListByIdList(param), echoUser: (param) userCenterApi.userCenterGetUserListByIdList(param) }对应的回显接口定义在 snowy-admin-web/src/api/sys/userCenterApi.jsuserCenterGetPositionListByIdList/userCenterGetUserListByIdList均接收{ idList: [...] }返回实体列表。因此若你的下拉数据在编辑回显时可能查不到名字建议给xn-page-select一并绑定:echo-function。八、滚动到底自动加载下一页的实现原理作为懒加载下拉翻页行为完全由滚动触发。组件源码中handlePopupScroll(e)监听下拉面板滚动事件当scrollTop 2 clientHeight scrollHeight即滚动接近底部、预留 2px 容差时调用handlePagination()handlePagination()先判断options.value.length total.value还有数据未加载再以current 1请求下一页成功后将新records与现有options合并并按id去重后回填整个加载过程由a-spinspinning包裹避免用户看到闪空的中间状态。此外组件针对搜索与非搜索两种形态分别渲染了两个a-select分支v-ifprops.showSearch源码注释说明这是重写两边是因为可能是个 antdv 的 bug 影响到我们的控制台输出错误属于防御性写法使用上无需感知。九、后端配套接口以职位选择器为例要完整落地一个 XnPageSelect 场景前端page-function背后需要有对应的分页接口。以仓库内置的职位选择器为例链路如下前端 API 定义在 snowy-admin-web/src/api/sys/userApi.jsuserPositionSelector(data)请求/sys/user/positionSelectorGET后端 Controller 位于 SysUserController.javaGetMapping(/sys/user/positionSelector)返回CommonResultPageSysPosition核心查询逻辑在 SysUserServiceImpl.java 的positionSelector方法中仅查询少量必要字段id、orgId、name、category、sortCode降低下拉接口的传输成本支持orgId精确过滤联动刷新的数据基础与searchKey对name的like模糊匹配服务端搜索的数据基础按sortCode升序排序返回 MyBatis-Plus 分页结果。业务侧人员管理模块有同构实现接口BizUserController.positionSelector见 BizUserController.java与 BizPositionServiceImpl.java 中的positionSelector额外叠加了登录用户数据范围StpLoginUserUtil.getLoginUserDataScope()的过滤以及CommonSqlUtil.safeIn防注入处理。你自定义的下拉接口完全可以参照这套模式分页返回 少量字段 orgId 过滤 搜索词模糊匹配即可无缝对接 XnPageSelect。十、在代码生成器中的自动集成XnPageSelect 并非孤立的页面组件它已被深度集成进 Snowy 的代码生成插件。在 snowy-admin-web/src/views/gen/config.vue 的字段配置中effectType可选值就包含positionSelector、positionSelectorMulti、groupSelector、userSelector、orgSelector等选择器类型后端生成的 Controller 模板backend-table/Controller.java.btl、backend-tree/Controller.java.btl 等会自动生成positionSelector分页接口前端模板frontend-table/Api.js.btl 等也会自动生成对应的选择器 API 与表单控件。这意味着通过代码生成器建出的业务模块默认就能获得与平台一致的分页下拉选择体验无需手写一遍对接代码。十一、注意事项与常见问题page-function必须绑定且必须返回 Promise它是组件数据来源的唯一入口漏绑时组件静默不请求源码中if (props.pageFunction)直接返回下拉将无数据可选。records命名必须为{ name, id }id是提交的valuename是展示文本字段名不一致时务必在page-function内重封装并保留total、current分页元信息。搜索与本地过滤的取舍showSearch开启后走的是服务端搜索filterOption会被关闭不要指望前端对已加载数据做本地过滤若需本地过滤不要开启showSearch。联动刷新记得重置依赖字段如示例中组织变更后除onPage({ orgId })外还应把旧组织下的positionId、directorId清空防止脏数据提交。编辑回显记得绑定echo-function当选中值不在当前分页结果中时组件靠echoFunction({ idList })反查回显未绑定则编辑态可能只显示 ID 或空白。后端接口建议只查必要字段参考平台内置positionSelector的实现选择器接口只 selectid、name等展示所需字段并支持orgId、searchKey两个可选参数兼顾性能与复用。结语XnPageSelect 把分页懒加载 服务端搜索 滚动翻页 编辑回显完整封装进一个与a-select用法几乎一致的下拉组件是 Snowy 中处理大数据量下拉选择的标准答案。掌握它的四个额外属性pageFunction、pageSize、showSearch、searchKeyName、一个内置方法onPage以及{ name, id }数据契约再配合后端分页接口的orgId过滤与searchKey模糊匹配你便可以在任意业务表单中快速落地一套可搜索、可分页、可联动、可回显的选择器方案。更多源码细节可继续阅读 XnPageSelect/index.vue 及其配套文档 README.md。赞分享后端前端认证鉴权应用安全【免费下载链接】Snowy国内首个国密前后分离快速开发平台《免费商用》基于开源技术栈精心打造融合Vue3AntDesignVue4Vite5SpringBoot3MpHuToolSa-Token。平台内置国密加解密功能保障前后端数据传输安全全面支持国产化环境适配多种机型、中间件及数据库。特别推荐插件提供工作流、多租户、多数据源、即时通讯等高级插件灵活接入让您的项目开发如虎添翼。项目地址https://gitcode.com/xiaonuobase/Snowy点击查看免费下载相关推荐Ant Design表单多选下拉搜索Select与搜索功能Ant Design表单多选下拉搜索Select与搜索功能 在企业级应用开发中表单是数据收集的核心组件。当面对大量选项或需要快速定位特定内容时普通的下拉选UI组件前端设计系统ant-design-blazor 列表选择器Table Select实战用 Select 自定义下拉模板集成表格选择ant design blazor 列表选择器Table Select实战用 Select 自定义下拉模板集成表格选择 导读 本篇文章聚焦 ant des前端UI组件设计系统ant-design-blazor 列表选择器实战用 Select 的 DropdownRender 自定义下拉模板嵌入 Tableant design blazor 列表选择器实战用 Select 的 DropdownRender 自定义下拉模板嵌入 Table 导读 本篇围绕 antUI组件前端上一篇戴尔G15散热控制终极指南告别AWCC拥抱开源解决方案下一篇3步快速实现智慧树自动刷课免费的Chrome扩展学习助手终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

MBENET Modbus驱动深度解析:从协议原理到配置调试与避坑指南

MBENET Modbus驱动深度解析:从协议原理到配置调试与避坑指南

简介:MBENET驱动是面向工业自动化与Modbus TCP通信场景的Modbus驱动程序资源,帮助设备或系统通过以太网与PLC、HMI等设备进行标准化的数据交换。压缩包共包含101个文件,以DLL运行库、EXE工具程序和CHM帮助文档为主,另含HLP、PDF、…

📅 2026/10/16 2:01:31
LAMMPS fix lb/viscous 命令详解:将格子玻尔兹曼流体水动力作用于粒子

LAMMPS fix lb/viscous 命令详解:将格子玻尔兹曼流体水动力作用于粒子

科研科学计算高性能计算 【免费下载链接】lammps Public development project of the LAMMPS MD software package 项目地址: https://gitcode.com/gh_mirrors/la/lammps 点击查看 免费下载 导读 fix lb/viscous 是 LAMMPS LATBOLTZ 包中与 fix lb/fluid 配套的核…

📅 2026/10/16 2:01:31
零基础完整教程:3 分钟让 Hermes 自我进化 AI Agent 跑通 DeepSeek 接入

零基础完整教程:3 分钟让 Hermes 自我进化 AI Agent 跑通 DeepSeek 接入

零基础完整教程:3 分钟让 Hermes 自我进化 AI Agent 跑通 DeepSeek 接入 【免费下载链接】awesome-deepseek-agent 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-deepseek-agent 大约 3 分钟、2 条命令、3 个参数,就能让 Hermes 自…

📅 2026/10/16 2:01:31
MORE NEWS

更多资讯

📰

屏译「自动适配画面」如何实现?漫画气泡检测、原文擦除与背景修复原理全解析

【免费下载链接】overlay-translator 无需 ROOT 的开源 Android 屏幕实时翻译工具,适合游戏、视觉小说和漫画。支持端侧与云端 OCR、离线 LLM、多种翻译服务和文字朗读(TTS),译文可直接显示在画面上。Open-source no-root Android…

📰

Rust RFC 3983 深度解析:为什么 Rust 需要 `f16b`——16 位 Brain 浮点类型的设计与落地

文档 【免费下载链接】rfcs RFCs for changes to Rust 项目地址: https://gitcode.com/gh_mirrors/rf/rfcs 点击查看 免费下载 本文基于 Rust RFC 仓库中的 RFC 3983(bf16) 展开,系统讲解 Rust 社区为何要在 core::num 中引入新的…

📰

MooTool Next Compose Vault MCP 授权路径 `realpath` 对齐 Electron 解析:从符号链接误授权到 canonical 路径强制校验

桌面应用开发工具 【免费下载链接】MooTool Handy tool set for developers 项目地址: https://gitcode.com/gh_mirrors/mo/MooTool 点击查看 免费下载 导读 在 MooTool Next 系列产品的 Compose(next-compose)桌面端中,Vault M…

📰

10分钟跑通第一条查询:internship-warehouse数据集快速上手教程(HF datasets流式+DuckDB双方案实战)

数据集数据工程数据分析 【免费下载链接】internship-warehouse 项目地址: https://ai.gitcode.com/hf_mirrors/FlyRank/internship-warehouse 点击查看 免费下载 想快速跑通 internship-warehouse 数据集的第一条查询吗?这是一个由 FlyRank 发布的、约…

📰

老 Mac 装新 macOS:用 OpenCore Legacy Patcher 四步完成系统升级与显卡补丁

老 Mac 装新 macOS:用 OpenCore Legacy Patcher 四步完成系统升级与显卡补丁 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 老 Intel Mac 被 App…

📰

PEEK与PEKK选型指南:从分子结构到工艺窗口的工程实践

简介:这份PDF是基础化工行业专题研究报告,聚焦聚醚醚酮(PEEK)与聚醚酮酮(PEKK)两类高性能热塑性材料,面向化工、新材料领域的研究人员、投资分析者及产业从业者,帮助系统理解二者的结…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬