基于 UniApp 的弹出层选择器单选、多选组件,支持单选、多选、搜索、数量输入等功能。专为移动端优化,提供丰富的交互体验。

yu-select 选择器组件

基于 UniApp 的弹出层选择器单选、多选组件,支持单选、多选、搜索、数量输入等功能。专为移动端优化,提供丰富的交互体验。

效果

地址

插件市场

gitee

功能特性

  • 多种选择模式:支持单选(radio)和多选(checkbox)模式
  • 智能搜索:内置搜索功能,支持实时过滤,大小写不敏感
  • 数量管理:支持数量输入框,可设置选项数量
  • 默认值设置:支持单选和多选的默认值预设
  • 下拉加载:支持滚动到底部加载更多数据
  • 全选功能:多选模式下支持一键全选/全不选
  • 交互优化:支持点击选中/取消,数量输入自动选中
  • 视觉反馈:选中状态高亮显示,已选标签展示
  • 多端适配:响应式设计,完美支持H5、小程序、App
  • 清空功能:支持一键清空所有选择和数量
  • 防误触:弹窗滚动不影响背景页面

安装使用

  1. uni_modules/yu-select 目录复制到您的 UniApp 项目的 uni_modules 目录下
  2. 在页面中引入组件:
vue 复制代码
<template>
  <yu-select 
    :show="showSelect" 
    :dataLists="dataList" 
    @cancel="showSelect = false" 
    @submit="handleSelectSubmit"
  />
</template>

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

const showSelect = ref(false);
const dataList = ref([
  { label: '选项1', value: 1 },
  { label: '选项2', value: 2 },
  // ...
]);

function handleSelectSubmit(selectedData) {
  console.log('选中的数据:', selectedData);
}
</script>

Props 属性

属性名 类型 默认值 说明 备注
dataLists Array [] 数据列表 对象数组,每个对象需包含nameKey和valueKey字段
nameKey String 'label' 显示名称的字段名 用于列表项显示的文本字段
valueKey String 'value' 值字段名 用作唯一标识的字段
numKey String 'num' 数量字段名 showNum为true时使用的数量字段
show Boolean false 是否显示弹窗 控制组件的显示隐藏
type String 'radio' 选择类型 'radio'单选 / 'checkbox'多选
showSearch Boolean true 是否显示搜索框 开启后可实时搜索过滤数据
showNum Boolean false 是否显示数量输入框 开启后每个选项可输入数量
popupTitle String '列表选择' 弹窗标题 显示在弹窗顶部的标题文字
placeholder String '请输入搜索内容' 搜索框占位符 搜索输入框的提示文字
isClearable Boolean false 是否可清空 设为true时会清空所有选择和数量
defaultValue String/Number/Array null 默认选中值 单选传值,多选传数组

Events 事件

事件名 参数 说明 触发时机
search keyword 搜索事件,返回搜索关键词 用户输入搜索内容时实时触发
lower - 滚动到底部事件,用于加载更多 列表滚动到底部时触发
cancel - 取消选择事件 点击取消按钮或遮罩层时触发
submit selectedData 提交选择事件,返回选中的数据 点击确认按钮时触发

使用示例

基本单选示例

vue 复制代码
<yu-select 
  :show="showSelect" 
  :dataLists="listData" 
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

多选带数量示例

vue 复制代码
<yu-select 
  :show="showSelect" 
  type="checkbox" 
  :showNum="true" 
  :dataLists="listData" 
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

设置默认值

vue 复制代码
<!-- 单选默认值 -->
<yu-select 
  :show="showSelect" 
  :defaultValue="1" 
  :dataLists="listData" 
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

<!-- 多选默认值 -->
<yu-select 
  :show="showSelect" 
  type="checkbox"
  :defaultValue="[1, 2]" 
  :dataLists="listData" 
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

带搜索和下拉加载

vue 复制代码
<yu-select 
  :show="showSelect" 
  :dataLists="listData" 
  placeholder="输入工站名称搜索"
  @cancel="showSelect = false" 
  @submit="handleSubmit"
  @search="handleSearch"
  @lower="loadMore"
/>

<script setup>
function handleSearch(keyword) {
  console.log('搜索关键词:', keyword);
  // 处理搜索逻辑
}

function loadMore() {
  console.log('加载更多数据');
  // 处理分页加载
}
</script>

清空功能

vue 复制代码
<yu-select 
  :show="showSelect" 
  :isClearable="needClear"
  :dataLists="listData" 
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

<script setup>
const needClear = ref(false);

// 触发清空
function clearSelection() {
  needClear.value = true;
  nextTick(() => {
    needClear.value = false;
  });
}
</script>

自定义字段名

vue 复制代码
<yu-select 
  :show="showSelect" 
  :dataLists="customData" 
  nameKey="cworkStationName"
  valueKey="id"
  numKey="quantity"
  :showNum="true"
  @cancel="showSelect = false" 
  @submit="handleSubmit"
/>

<script setup>
const customData = ref([
  { id: 1, cworkStationName: '工作站A', quantity: 0 },
  { id: 2, cworkStationName: '工作站B', quantity: 0 }
]);
</script>

数据格式

组件期望的数据格式为对象数组,每个对象至少包含 nameKeyvalueKey 对应的字段:

标准格式

javascript 复制代码
const dataList = [
  { label: '选项1', value: 1, num: 0 },
  { label: '选项2', value: 2, num: 0 },
  { label: '选项3', value: 3, num: 0 }
];

自定义字段格式

javascript 复制代码
const customDataList = [
  { id: 1, cworkStationName: '工作站A', quantity: 0 },
  { id: 2, cworkStationName: '工作站B', quantity: 5 },
  { id: 3, cworkStationName: '工作站C', quantity: 3 }
];

// 对应的组件配置
// nameKey="cworkStationName" valueKey="id" numKey="quantity"

字段说明

  • nameKey字段:必需,用于显示的文本内容
  • valueKey字段:必需,用作唯一标识,支持字符串或数字
  • numKey字段:可选,当showNum为true时使用,存储数量值

返回值格式

组件通过 submit 事件返回选中的数据,格式如下:

单选模式 (type="radio")

返回单个选中的对象,如果未选中则返回空对象:

javascript 复制代码
// 有选中项
{ label: '选项1', value: 1, num: 5 }

// 未选中
{}

多选模式 (type="checkbox")

返回选中的对象数组:

javascript 复制代码
// 选中多项
[
  { label: '选项1', value: 1, num: 5 },
  { label: '选项2', value: 2, num: 3 }
]

// 未选中任何项
[]

处理返回数据

javascript 复制代码
function handleSubmit(selectedData) {
  if (type === 'radio') {
    if (selectedData && selectedData.value) {
      console.log('选中的值:', selectedData.value);
      console.log('选中的文本:', selectedData.label);
      console.log('输入的数量:', selectedData.num);
    } else {
      console.log('未选中任何项');
    }
  } else {
    console.log('选中的项数:', selectedData.length);
    selectedData.forEach(item => {
      console.log(`${item.label}: ${item.num || 0}`);
    });
  }
}

样式定制

组件使用 SCSS 编写样式,提供完整的主题色配置:

主题变量

scss 复制代码
// 主题色配置
$primary-color: #2B8BE4;        // 主题色
$primary-light: #EBF5FD;        // 浅色背景
$primary-text: #0076F9;         // 主要文字色

自定义主题

可以通过覆盖这些变量来自定义样式:

scss 复制代码
// 在你的全局样式文件中
$primary-color: #007AFF;        // 自定义主题色
$primary-light: #E3F2FD;        // 自定义浅色背景
$primary-text: #1976D2;         // 自定义文字色

@import '@/uni_modules/yu-select/components/yu-select/yu-select.vue';

关键样式类

  • .popup-mask: 遮罩层样式
  • .popup-content: 弹窗内容区域
  • .search-box: 搜索框样式
  • .select-row: 列表行样式
  • .custom-radio-icon / .custom-checkbox-icon: 选择图标样式
  • .bottons: 底部按钮区域样式

浏览器兼容性

  • ✅ H5
  • ✅ 微信小程序
  • ✅ App
  • ✅ 其他小程序平台

高级用法

交互行为优化

组件提供了多种智能交互:

  1. 点击切换选择:点击已选中项可取消选择
  2. 数量输入联动
    • 输入数量大于0自动选中该项
    • 清空数量或输入0自动取消选择
  3. 搜索实时过滤:输入关键词实时过滤列表
  4. 全选功能:多选模式下支持一键全选/取消全选

性能优化

javascript 复制代码
// 大量数据时建议使用分页加载
function loadMore() {
  if (loading || !hasMore) return;
  loading = true;
  
  // 模拟接口请求
  setTimeout(() => {
    const newData = generateData(currentPage + 1);
    dataLists.value.push(...newData);
    currentPage++;
    loading = false;
  }, 500);
}

状态管理

javascript 复制代码
// 使用组合式API管理选择状态
const { selectedData, showSelect, handleSubmit } = useSelect();

function useSelect() {
  const selectedData = ref([]);
  const showSelect = ref(false);
  
  function handleSubmit(data) {
    selectedData.value = data;
    showSelect.value = false;
    // 处理业务逻辑
  }
  
  return {
    selectedData,
    showSelect,
    handleSubmit
  };
}

注意事项

  1. 滚动穿透防护 :组件使用了 touchmove.stop.prevent 来防止弹窗内滚动影响外部页面
  2. 数量输入限制 :数量输入框仅在 showNum="true" 时显示,支持数字类型输入
  3. 搜索功能 :搜索功能默认开启,可通过 showSearch="false" 关闭,搜索不区分大小写
  4. 多端适配:组件会自动处理各端的样式差异,特别是安全区域适配
  5. 数据响应式:dataLists 变化时组件会自动更新,支持动态数据源
  6. 内存管理:大量数据时建议使用虚拟滚动或分页加载避免性能问题
  7. 字段映射:确保 dataLists 中的对象包含正确的 nameKey 和 valueKey 字段
  8. 默认值设置:defaultValue 仅在组件初始化时生效,后续变化需要手动处理

更新日志

v1.1.0 (2025-09-24)

功能增强

  • ✨ 新增点击选中项可取消选择的交互优化
  • ✨ 新增数量输入与选择状态的智能联动
  • ✨ 优化搜索功能,支持大小写不敏感搜索
  • ✨ 新增已选标签展示功能(多选模式)
  • ✨ 改进全选/全不选的用户体验
  • ✨ 新增清空搜索按钮,提升操作便利性
  • 🐛 修复数量输入框在不同选择状态下的显示问题
  • 🐛 修复默认值设置在某些情况下不生效的问题
  • 💄 优化UI细节,提升视觉体验
  • 📝 完善组件注释和文档

技术改进

  • 🔧 优化数据初始化和更新逻辑
  • 🔧 改进组件内部状态管理
  • 🔧 增强多端兼容性处理
  • ⚡ 提升搜索性能和响应速度

v1.0.0 (2025-09-23)

初始版本发布

  • ✅ 支持单选/多选模式
  • ✅ 支持搜索功能
  • ✅ 支持数量输入
  • ✅ 支持默认值设置
  • ✅ 支持下拉加载更多
  • ✅ 基础UI和交互实现

常见问题

Q: 如何实现异步数据加载?

A: 使用 @lower 事件监听滚动到底部,在回调中加载更多数据:

javascript 复制代码
function loadMore() {
  if (!hasMore || loading) return;
  // 异步加载数据并追加到 dataLists
}

Q: 如何自定义选择图标样式?

A: 可以通过覆盖 .custom-radio-icon.custom-checkbox-icon 类来自定义:

scss 复制代码
.custom-radio-icon .circle.checked {
  background: your-color;
  border-color: your-color;
}

Q: 搜索功能支持哪些匹配规则?

A: 目前支持模糊匹配,匹配 nameKey 字段内容,不区分大小写。

Q: 如何处理大量数据的性能问题?

A: 建议使用分页加载或虚拟滚动,避免一次性渲染过多DOM元素。

Q: 组件支持哪些平台?

A: 支持 H5、微信小程序、App 等 UniApp 支持的所有平台。

技术支持

如果您在使用过程中遇到问题,可以通过以下方式获取帮助:

  1. 查看本文档的常见问题部分
  2. 检查控制台是否有错误信息
  3. 确认数据格式是否正确
  4. 验证组件属性配置是否有误

作者

Yu - 专注于移动端组件开发

许可证

MIT License


💡 提示:建议在使用前先查看示例代码,了解组件的基本用法和配置方式。如需更复杂的功能,可以基于组件进行二次开发。

相关推荐
racerun3 小时前
CSS Display Grid布局 grid-template-columns grid-template-rows
开发语言·前端·javascript
一只毛驴3 小时前
Canvas 的基本使用及动画效果
前端·javascript
行走在顶尖3 小时前
JS场景应用
前端
isyangli_blog3 小时前
(3-1) Html
前端·html
Yan-英杰3 小时前
Amazon SES + NestJS 实战:零成本打造高送达率邮箱验证方案
java·服务器·前端·网络·数据库·ai
weixin_456904274 小时前
Vue电商数据分析大屏开发
前端·vue.js·数据分析
玖笙&4 小时前
✨Vue 静态路由详解:构建应用的导航骨架(4)
前端·javascript·vue.js
这是个栗子4 小时前
(二)Vue.js 指令、事件与计算属性
前端·javascript·vue
黑客飓风4 小时前
Chrome性能优化指南
前端·chrome·性能优化