官方推荐使用uni-data-select并设filterable="true",因其多端兼容、开箱即用;手动组合picker+input易遇样式失控、索引错乱、键盘冲突、性能卡顿等密集坑点。
直接用 uni-data-select,设 filterable="true" 就行——这是官方推荐、多端兼容、开箱即用的方案,不用自己写过滤逻辑,也不用处理 ios 键盘遮挡或滚动穿透。
为什么不用 picker + input 手动组合?
这种组合看似简单,但实际踩坑密集:
-
picker在 H5 端会退化成原生<select></select>,样式完全不可控,也无法高亮关键词或监听输入过程 - 在小程序里,
picker的range更新后不会自动重置选中索引,容易导致@change返回错误下标 - iOS 真机上,
input聚焦后弹出键盘,再点picker会触发两次软键盘(一次收起、一次弹出),体验断裂 - 数据量稍大(比如 >100 条)时,每次
@input都全量filter,无防抖就卡顿明显
uni-data-select 的关键配置和避坑点
它不是“拿来就能搜”,几个字段必须对齐,否则搜索失效:
-
:localdata必须是数组,每项含value和text字段;传对象或少字段会静默失败 -
filterable设为true后,搜索逻辑默认对text做includes(区分大小写),如需模糊匹配,得自己重写customFilter方法 - 分类标题要显示?不能直接传带
children的嵌套结构,得拍平成数组,并插入占位项:{ value: '', text: '热门品牌', disabled: true },再配:disabled-field="'disabled'" - H5 正常,但微信小程序需确保基础库 ≥ 2.10.3,否则
popup层可能被遮挡或 touchmove 穿透
数据量大时怎么不卡?
超过 200 条选项时,别让整个列表一次性渲染并过滤:
- 启用
lazy-load,配合@loadmore实现滚动加载 - 远程搜索场景下,不要在
@input里直接发请求——先加 300ms 防抖(setTimeout清上一个 timer),再调uni.request - 避免把完整对象塞进
localdata,只保留value/text,减少内存占用和 diff 开销 - 如果必须本地全量搜索,用
indexOf替代正则,性能高 3–5 倍
最易被忽略的是:搜索行为和选择行为在业务上往往需要区分——用户是“从列表选了一个”,还是“输了一个新值”?uni-data-select 不提供这个语义,若后端要求明确标识来源,就得换 superwei-combox 并监听 @input 和 @select 两个事件分开处理。


















