ElSelect二次封装组件实现分页(下拉加载、缓存)、回显功能实例

 更新时间:2026年06月22日 09:52:20   作者:穷鱼子酱  
在Vue3的生态中,组件二次封装是每个中高级开发者必须掌握的技能,这篇文章主要介绍了ElSelect二次封装组件实现分页(下拉加载、缓存)、回显的相关资料,需要的朋友可以参考下

前言

一个基于 Vue 3 + Element Plus 的 <el-select> 封装组件:支持远程搜索分页加载(无限加载/触底加载)、可选缓存与可选回显(detailApi),适合“远程大数据下拉选择”的场景。

1. 安装

npm i select-pagination-element-plus

2. 快速开始(最小可用)

下面示例展示最基本用法:输入关键词 → 远程查询 → 下拉触底继续加载。

<template>
  <SelectPagination v-model="value" :api="fetchUsers" placeholder="输入关键词搜索" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import SelectPagination from 'select-pagination-element-plus'

const value = ref('')

const fetchUsers = async (params: any) => {
  // params 内默认会包含:page、size、name(可配置)
  // 你也可以通过组件 props.params 传额外查询参数

  // 约定返回结构:默认 responsePath = "data.data"
  // responsePath 指向的对象必须包含:
  // - content: 选项数组
  // - totalElements: 总数量
  return {
    data: {
      data: {
        content: [
          { id: 'u-1', label: '用户 1', value: 'u-1' },
          { id: 'u-2', label: '用户 2', value: 'u-2' }
        ],
        totalElements: 2
      }
    }
  }
}
</script>

3. 后端返回结构(responsePath)

组件会通过 responsePath 在响应对象中定位分页数据,默认:

  • responsePath = "data.data"

该路径最终需要指向一个对象,且至少包含:

{
  content: any[]
  totalElements: number
}

3.1 示例:后端返回是{ data: { list, total } }

你可以这么配置:

<SelectPagination
  v-model="value"
  :api="fetchUsers"
  response-path="data"
/>

并确保 fetchUsers 返回里 data 对象包含 content/totalElements,或者你在 fetchUsers 内转换成统一结构。

4. 参数说明(Props 字段含义)

4.1 数据与行为

参数类型默认值含义(建议阅读)
modelValuestring | number | any[]''v-model 值,单选为标量,多选为数组
isRemotebooleantrue是否启用 Element Plus 的 remote 模式;为 true 时会走远程搜索逻辑
api(params) => Promise<any> | any() => (params) => Promise<any> | any-拉取分页列表的函数(见第 5 节)
apiAsyncbooleanfalsetrue 时,api 被视为“工厂函数”,会 await api() 得到真正的请求函数
paramsobject | () => object{}每次请求都会合并的额外参数;用函数可动态生成(比如依赖外部响应式条件)
initOptionsany[][]初始选项(常用于预置、默认项、或者本地固定项),会合并进 options

4.2 字段映射(label/value)

参数类型默认值含义
labelFieldstring'label'option 显示文本字段名
valueFieldstring'value'option 实际值字段名

例如你的后端返回 [{ userId, userName }],可以:

<SelectPagination
  v-model="value"
  :api="fetchUsers"
  label-field="userName"
  value-field="userId"
/>

4.3 分页与搜索参数(发给后端的字段名)

参数类型默认值含义
pageSizenumber10每页数量
pageKeystring'page'页码字段名(发给后端的 key)
sizeKeystring'size'每页大小字段名
keywordstring'name'搜索关键词字段名(也就是 query 的 key)

举例:默认请求参数类似:

{
  page: 1,
  size: 10,
  name: "张"
}

如果你的后端是 current/limit/keyword

<SelectPagination
  v-model="value"
  :api="fetchUsers"
  page-key="current"
  size-key="limit"
  keyword="keyword"
/>

4.4 响应路径

参数类型默认值含义
responsePathstring'data.data'用点号路径从响应中取分页对象(见第 3 节)

4.5 缓存(提高体验,减少重复请求)

参数类型默认值含义
enableCachebooleantrue是否缓存:已加载 options、页码、关键词等
cacheKeystring''缓存命名空间;为空时内部会用 api.name + params 生成一个 key

缓存适用场景:下拉多次分页加载后关闭再打开,希望还停留在上次加载的结果与位置。

4.6 回显与详情(detailApi / changeDetail)

参数类型默认值含义
changeDetailbooleanfalsetrue 时,选中后会额外触发 change-detail 事件,把选中项的 option 数据回传
detailApi(value) => Promise<any> | anynull用于“回显”:当 modelValue 有值但 options 里没有对应项时,用 value 拉取详情并插入 options

典型场景:表单编辑页从后端拿到 userId,但下拉列表还没加载;此时通过 detailApi(userId) 把该用户详情拉回来做回显。

4.7 样式与触底哨兵

参数类型默认值含义
popperClassstring''额外传给 el-select 的 popper-class,用于定制下拉面板样式作用域
footerSentinelIdstring''自定义 footer sentinel 的 DOM id;内部用它定位触底观察点(一般不需要传)

5. api 的写法(最重要)

组件会在这些时机调用 api(params)

  • 下拉打开且无缓存(或缓存为空)时
  • 输入关键词触发远程搜索时
  • 触底(或点击“加载更多”)时拉取下一页

5.1 api(params) 直接是请求函数

const api = async (params: any) => {
  return request.get('/users', { params })
}

5.2 apiAsync = true:api 先返回请求函数(适合依赖异步初始化)

<SelectPagination v-model="value" :api="createApi" :api-async="true" />
const createApi = async () => {
  const token = await getTokenSomehow()
  return (params: any) => request.get('/users', { params, headers: { token } })
}

6. 事件(Events)

事件名参数说明
update:modelValueanyv-model 更新
changeany同 Element Plus 的 change
change-detailany | any[] | nullchangeDetail = true 时返回选中项详情(单选返回对象,多选返回数组)

7. 插槽(Slots)

7.1 footer:完全自定义“加载中/没有更多/加载更多”

slot props:

  • loading: boolean 当前是否在请求
  • hasMore: boolean 是否还有下一页
  • options: any[] 当前已加载的 options
  • loadMore: () => void 主动触发加载更多

示例:

<SelectPagination v-model="value" :api="fetchUsers" footer-sentinel-id="user-select-footer">
  <template #footer="{ loading, hasMore, loadMore }">
    <div v-if="loading" style="padding: 8px 0; text-align: center">加载中...</div>
    <div v-else-if="!hasMore" style="padding: 8px 0; text-align: center">没有更多了</div>
    <div v-else style="padding: 8px 0; text-align: center; cursor: pointer" @click="loadMore">
      点击加载更多
    </div>
  </template>
</SelectPagination>

8. 暴露方法(ref)

通过组件 ref 访问:

  • loadData(isReset?: boolean):加载数据,传 true 表示重置并从第一页开始
  • clearCache():清除缓存
  • restoreCache():手动恢复缓存(返回是否成功)
  • updateValue(val):手动更新值(会触发 v-model/change)
  • loadEchoData():手动触发回显数据拉取
  • setPage(page: number):设置页码(一般调试用)
  • setOptions(options: any[]):直接覆盖 options(一般调试用)
  • options:当前 options 的 ref
  • currentPage:当前页码的 ref

总结

到此这篇关于ElSelect二次封装组件实现分页(下拉加载、缓存)、回显功能的文章就介绍到这了,更多相关ElSelect二次封装组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3表单参数校验及正则表达式举例详解

    vue3表单参数校验及正则表达式举例详解

    最近项目中有一个校验身份证号手机号的业务,索性给大家总结下,这篇文章主要给大家介绍了关于vue3表单参数校验及正则表达式的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • vue如何解决轮播图(Swiper)第一张图片一闪而过问题

    vue如何解决轮播图(Swiper)第一张图片一闪而过问题

    这篇文章主要介绍了vue如何解决轮播图(Swiper)第一张图片一闪而过问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • vue3常用响应式对象的api,你全用过了吗

    vue3常用响应式对象的api,你全用过了吗

    这篇文章主要给大家介绍了关于vue3常用响应式对象api的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用vue3具有一定的参考学习价值,需要的朋友可以参考下
    2023-02-02
  • Vue3实现Element Plus表格的多选功能与条件操作

    Vue3实现Element Plus表格的多选功能与条件操作

    Element-plus是ElementUI的升级版,是一套基于vue2与vue3的桌面端组件库,它提供了丰富的组件帮助开发人员快速构建功能强大、风格统一的页面,本文给大家介绍了Vue3实现Element Plus表格的多选功能与条件操作,需要的朋友可以参考下
    2024-08-08
  • 一文搞明白vue开发者vite多环境配置

    一文搞明白vue开发者vite多环境配置

    Vue是一款流行的JavaScript框架,用于开发动态单页应用程序,本地安装和环境配置是学习和使用Vue的第一步,下面这篇文章主要给大家介绍了关于vue开发者vite多环境配置的相关资料,需要的朋友可以参考下
    2023-06-06
  • vue请求后端数据和跨域问题解决

    vue请求后端数据和跨域问题解决

    这篇文章主要介绍了vue请求后端数据和跨域问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • vue之proxyTable代理超全面配置方式

    vue之proxyTable代理超全面配置方式

    本文作者分享了使用Vue进行代理配置的个人经验,介绍了如何使用proxyTable进行跨域请求配置,并提供了具体的配置文件和使用方法,便于同行参考和学习
    2024-10-10
  • Vue中Table组件Select的勾选和取消勾选事件详解

    Vue中Table组件Select的勾选和取消勾选事件详解

    这篇文章主要为大家详细介绍了Vue中Table组件Select的勾选和取消勾选事件详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • 解决使用vue-awesome-swiper组件手动滚动点击失效问题

    解决使用vue-awesome-swiper组件手动滚动点击失效问题

    这篇文章主要介绍了使用vue-awesome-swiper组件手动滚动点击失效问题解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • vue项目配置使用flow类型检查的步骤

    vue项目配置使用flow类型检查的步骤

    这篇文章主要介绍了vue项目配置使用flow类型检查的步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03

最新评论