更新记录

1.0.0(2026-09-01) 下载此版本

  • 输入框 + 下方可滚动选择列表,点击展开,点击遮罩/外部关闭
  • 支持一键清除选中值(clearable)
  • 支持上拉加载:滚动条触碰最底部且无数据加载时触发 loadMore 回调(配合 loading 防重复触发)
  • 支持模糊搜索:输入关键词防抖后触发 search 回调接口,支持远程搜索(remote)与本地过滤(local)两种模式
  • 支持 v-model 双向绑定、disabled 禁用、自定义字段映射(labelKey / valueKey)与空态/加载态文案
  • 零依赖,兼容微信小程序、H5、App(vue)

平台兼容性

uni-app(4.87)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - -

其他

多语言 暗黑模式 宽屏模式
× ×

fg-select-dropdown 下拉列表选择器

组件名:fg-select-dropdown(uni_modules easycom 自动引入,也可手动引入) 版本:1.0.0

类似管理平台下拉列表选择的组件:一个输入框 + 输入框下方展示的可选择列表。点击输入框展开列表,点击外部区域收起。纯组件零依赖,兼容微信小程序、H5、App(vue)

特性

  • 输入框 + 下方可滚动选择列表:点击输入框展开,点击透明遮罩 / 外部区域关闭
  • 一键清除选择:有选中值或有输入内容时显示清除按钮,点击一键清空
  • 上拉加载:滚动条触碰列表最底部且当前无数据加载loading 为 false)时触发 loadMore 回调,配合父组件 loading 状态防止重复请求
  • 模糊搜索触发回调接口:输入关键词防抖(默认 300ms)后触发 search 回调,由父组件调用搜索接口;也支持 local 模式按 label 本地模糊过滤
  • v-model 双向绑定、disabled 禁用、自定义字段映射(labelKey / valueKey)、空态 / 加载中 / 没有更多文案自定义

快速使用

uni_modules 插件默认开启 easycom,页面中直接使用即可,无需注册:

<fg-select-dropdown
    v-model="value"
    :list="list"
    :loading="loading"
    :has-more="hasMore"
    placeholder="请输入关键词搜索"
    @search="onSearch"
    @load-more="onLoadMore"
/>

手动引入

import FgSelectDropdown from '@/uni_modules/fg-select-dropdown/components/fg-select-dropdown/fg-select-dropdown.vue'
export default {
    components: { FgSelectDropdown }
}

属性说明

属性名 类型 默认值 说明
modelValue String / Number / Object / Array '' 选中值,支持 v-model,与列表项 valueKey 字段对应
placeholder String '请选择' 输入框占位符
list Array [] 下拉列表数据,每项需包含 labelKey / valueKey 对应字段
labelKey String 'label' 列表项显示文案字段名
valueKey String 'value' 列表项选中值字段名
searchable Boolean true 输入框是否可输入搜索;false 时输入框为只读展示,点击仅展开列表
filterMode String 'remote' remote 远程搜索(输入防抖触发 search 回调接口);local 本地按 label 模糊过滤
searchDebounce Number 300 搜索防抖毫秒数
clearOnInput Boolean true 输入时是否清空已选中值(远程搜索下旧选中值通常不再有效)
clearable Boolean true 是否显示一键清除按钮
disabled Boolean false 是否禁用
loading Boolean false 是否正在加载数据(父组件控制;true 时不触发 loadMore 并展示加载文案)
hasMore Boolean true 是否还有更多数据(false 且列表非空时展示「没有更多了」)
emptyText String '暂无数据' 空数据文案
loadingText String '加载中...' 加载中文案
noMoreText String '没有更多了' 没有更多文案
maxHeight String '400rpx' 下拉列表最大高度(rpx / px),决定列表可滚动区域
lowerThreshold Number 50 触底距离阈值(px),滚动条触碰底部附近即触发 loadMore
confirmType String 'search' 输入框键盘确认键类型(小程序)
placeholderStyle String '' 占位符样式

事件说明

事件名 参数 说明
update:modelValue value v-model 更新(选中 / 清除时)
change (value, item) 选中值变化(value 为选中值,item 为完整列表项)
select item 选中某个列表项
clear - 点击一键清除按钮
search keyword 模糊搜索回调(防抖后触发;清除时也会触发一次空关键词,用于重新加载完整列表)
loadMore - 上拉加载回调:滚动条触碰最底部且 loading 为 false 时触发
open - 下拉列表展开
close - 下拉列表关闭

完整示例:远程搜索 + 分页 + 上拉加载 + 一键清除

<template>
    <view class="page">
        <fg-select-dropdown
            v-model="userValue"
            :list="userList"
            :loading="loading"
            :has-more="hasMore"
            placeholder="请输入姓名搜索"
            @open="onOpen"
            @search="onSearch"
            @load-more="onLoadMore"
            @clear="onSearch('')"
            @change="onChange"
        />
    </view>
</template>

<script setup>
import { ref } from 'vue'

const userValue = ref('')
const userList = ref([])
const loading = ref(false)
const hasMore = ref(true)
const page = ref(1)
const keyword = ref('')

// 模拟分页搜索接口
function fetchList(kw, reset) {
    loading.value = true
    setTimeout(() => {
        const all = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十', '郑十一', '冯十二']
            .map((name, i) => ({ label: name, value: i + 1 }))
        const kwLower = (kw || '').toLowerCase()
        const filtered = all.filter((it) => it.label.toLowerCase().indexOf(kwLower) > -1)
        const size = 5
        const start = (reset ? 1 : page.value) - 1
        const data = filtered.slice(start * size, start * size + size)
        userList.value = reset ? data : userList.value.concat(data)
        hasMore.value = userList.value.length < filtered.length
        page.value = reset ? 2 : page.value + 1
        loading.value = false
    }, 400)
}

// 首次展开时加载第一页(list 为空时)
function onOpen() {
    if (userList.value.length === 0) fetchList('', true)
}

// 模糊搜索:输入防抖后触发,拉取第一页
function onSearch(kw) {
    keyword.value = kw
    page.value = 1
    fetchList(kw, true)
}

// 上拉加载:触底且未在加载时触发,追加下一页
function onLoadMore() {
    fetchList(keyword.value, false)
}

function onChange(val, item) {
    console.log('选中:', val, item)
}
</script>

本地过滤模式

数据量小、无需接口时,直接传入完整列表并开启 local

<fg-select-dropdown
    v-model="value"
    filter-mode="local"
    :list="options"
    placeholder="输入关键词过滤"
/>
const options = [
    { label: '北京', value: 1 },
    { label: '上海', value: 2 },
    { label: '广州', value: 3 }
]

注意事项

  • 下拉列表使用 scroll-view 滚动,内容高度超过 maxHeight 时才会出现滚动条并触发 loadMore;数据不足一屏时不会触发触底回调,属于正常行为
  • loadMore 的防重复触发依赖父组件同步 loading:接口请求期间务必把 loading 置为 true,返回后置 false
  • 展开时组件会渲染一层全屏透明遮罩用于点击外部关闭,页面其他区域被遮罩拦截(点击即关闭),属弹层式下拉的正常交互
  • 远程搜索下点击清除按钮会先清空值,再触发一次 search(''),以便父组件重新加载完整列表
  • labelvalue 字段可通过 labelKey / valueKey 映射为任意字段名(如 name / id

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。