uni-app中用input实现本地搜索需绑定v-model、用tolowercase()统一大小写比对、手写300ms防抖、分离原始数据与搜索结果、避免type="search"、低版本android用indexof替代includes并做polyfill。

uni-app 里怎么用 input 实现带搜索逻辑的本地过滤
直接用 input 绑定 v-model + 数组 filter() 就行,但要注意响应式更新和防抖。不加防抖的话,每敲一个字都触发一次过滤,尤其在长列表里会卡顿、重复渲染。
- 搜索关键词建议用
ref或data响应式变量,别用普通let变量,否则视图不更新 - 过滤时用
includes()最简单,但注意大小写:建议统一转成小写比对,比如item.title.toLowerCase().includes(keyword.toLowerCase()) - 防抖必须自己加,uni-app 没内置,推荐用
setTimeout+clearTimeout手写,延迟 300ms 足够平衡体验和实时性 - 别在
@input里直接写复杂过滤逻辑,抽成方法,方便复用和测试
为什么 onPullDownRefresh 和搜索不能共存?
因为下拉刷新会重置页面数据,包括你正在输入的 keyword 和已过滤的列表。用户刚输一半“苹果”,一刷新,输入框清空、结果变回全量,体验断裂。
- 解决办法是把
keyword和原始数据分开存:原始列表走data或const定义,搜索结果用计算属性或单独ref管理 -
onPullDownRefresh里只刷新原始数据(比如调 API 重新拉列表),然后手动触发一次搜索逻辑,保持关键词不变 - 如果用了
onReachBottom分页加载,更要小心:新数据追加后,得用当前keyword再过滤一遍,而不是直接push到已过滤数组里
搜索框聚焦/失焦时,键盘没弹起或不收起?
这是 iOS(尤其是微信小程序)和部分安卓 WebView 的常见表现,本质是 input 的 focus 行为没被正确触发,或被其他样式/层级阻断。
- 确保
input没加disabled或readonly,且父容器没有pointer-events: none - 真机调试时,iOS 微信里要等
onReady后再调this.$nextTick(() => inputRef.focus()),否则无效 - 安卓端若失焦后键盘不收,手动调
uni.hideKeyboard(),别依赖浏览器自动行为 - 别用
type="search"—— 在 H5 和小程序里行为不一致,统一用type="text"+ 右侧加个清空按钮更可控
uni-app 条件编译下,filter 在 App 端报错:找不到 includes 方法?
老版本 Android WebView(比如 4.4.x)的 JS 引擎不支持 String.prototype.includes,但 uni-app 默认不垫平这个 API。
- 最轻量解法:改用
indexOf() !== -1替代includes(),兼容性 100% - 如果项目已用大量
includes,可在main.js开头加 polyfill:if (!String.prototype.includes) { String.prototype.includes = function(search, start) { return this.indexOf(search, start) !== -1; }; } - App 端打包时勾选「启用 ES6 转 ES5」只能解决语法,不补 API,这点容易忽略
- 真机测试别只看开发工具模拟器,得拿低版本安卓机实测,尤其政务类客户常用旧设备
本地搜索看着简单,真正卡住人的往往是防抖时机、条件编译差异、还有键盘生命周期这些边缘细节。写完先在 iOS 微信、Android 旧机型、H5 三个环境各试一次,比多写十行逻辑还重要。










