yu-select 选择器组件
基于 UniApp 的弹出层选择器单选、多选组件,支持单选、多选、搜索、数量输入等功能。专为移动端优化,提供丰富的交互体验。
效果
地址
功能特性
- ✅ 多种选择模式:支持单选(radio)和多选(checkbox)模式
- ✅ 智能搜索:内置搜索功能,支持实时过滤,大小写不敏感
- ✅ 数量管理:支持数量输入框,可设置选项数量
- ✅ 默认值设置:支持单选和多选的默认值预设
- ✅ 下拉加载:支持滚动到底部加载更多数据
- ✅ 全选功能:多选模式下支持一键全选/全不选
- ✅ 交互优化:支持点击选中/取消,数量输入自动选中
- ✅ 视觉反馈:选中状态高亮显示,已选标签展示
- ✅ 多端适配:响应式设计,完美支持H5、小程序、App
- ✅ 清空功能:支持一键清空所有选择和数量
- ✅ 防误触:弹窗滚动不影响背景页面
安装使用
- 将
uni_modules/yu-select
目录复制到您的 UniApp 项目的uni_modules
目录下 - 在页面中引入组件:
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>
数据格式
组件期望的数据格式为对象数组,每个对象至少包含 nameKey
和 valueKey
对应的字段:
标准格式
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
- ✅ 其他小程序平台
高级用法
交互行为优化
组件提供了多种智能交互:
- 点击切换选择:点击已选中项可取消选择
- 数量输入联动 :
- 输入数量大于0自动选中该项
- 清空数量或输入0自动取消选择
- 搜索实时过滤:输入关键词实时过滤列表
- 全选功能:多选模式下支持一键全选/取消全选
性能优化
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
};
}
注意事项
- 滚动穿透防护 :组件使用了
touchmove.stop.prevent
来防止弹窗内滚动影响外部页面 - 数量输入限制 :数量输入框仅在
showNum="true"
时显示,支持数字类型输入 - 搜索功能 :搜索功能默认开启,可通过
showSearch="false"
关闭,搜索不区分大小写 - 多端适配:组件会自动处理各端的样式差异,特别是安全区域适配
- 数据响应式:dataLists 变化时组件会自动更新,支持动态数据源
- 内存管理:大量数据时建议使用虚拟滚动或分页加载避免性能问题
- 字段映射:确保 dataLists 中的对象包含正确的 nameKey 和 valueKey 字段
- 默认值设置: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 支持的所有平台。
技术支持
如果您在使用过程中遇到问题,可以通过以下方式获取帮助:
- 查看本文档的常见问题部分
- 检查控制台是否有错误信息
- 确认数据格式是否正确
- 验证组件属性配置是否有误
作者
Yu - 专注于移动端组件开发
许可证
MIT License
💡 提示:建议在使用前先查看示例代码,了解组件的基本用法和配置方式。如需更复杂的功能,可以基于组件进行二次开发。