uni-search-bar的@input事件需手动防抖,用setTimeout+clearTimeout实现300–500ms延迟触发,页面卸载前清除定时器,联想面板用v-if控制显隐,空输入、请求中、失败状态需分别处理,点击联想项后调用blur收键盘,并拦截过短关键词。

uni-search-bar 的 @input 事件必须手动防抖
uni-search-bar 的 @input 每次字符增删都触发,不是“用户停顿后才发”,输“北京”会连发 4 次请求。不加控制,轻则联想词跳变、结果错乱,重则后端被刷崩。
- 用
setTimeout+clearTimeout手写最稳:在 data 里定义searchTimer: null,handleInput中先clearTimeout(this.searchTimer),再赋新定时器 - 延迟设 300–500ms,太短起不到过滤作用,太长影响响应感
- 别把防抖逻辑塞进
@confirm——那是回车/搜索按钮触发的,和联想无关 - 页面卸载前必须
clearTimeout(this.searchTimer),否则内存泄漏
联想面板必须用 v-if 控制显隐,不能用 v-show
v-show 只是 display: none,DOM 仍在;v-if 才真正销毁节点。App 端(尤其 iOS)下拉面板若用 v-show,容易遮挡按钮、触发滚动错位、键盘收不起。
- 推荐判断逻辑:
v-if="showSuggestions && suggestionList.length" - 空输入、请求中、失败时状态要分开处理:请求中显示 loading,失败留空或提示“暂无建议”,别只靠数组长度判断
- 点击联想项后,立刻调用
searchBarRef.blur(),否则 iOS 键盘常卡住不收
搜索关键词长度和请求时机要主动拦截
搜单字(如“手”)返回几百条结果,既无意义又浪费资源。后端也难做有效分词,前端必须前置过滤。
- 在防抖回调里加校验:
if (val.length - 用户清空输入框时,直接清空列表、取消 pending 请求,不发空字符串请求
- 避免用
watch监听searchKeyword,除非设immediate: false,否则初始化就触发一次空查询 - 如果用本地过滤(比如匹配历史记录),和远程联想要明确区分路径,别混在同一函数里
历史记录得去重+限长+异步存取
localStorage 同步写入会阻塞 UI,尤其 App 端连续输入时明显卡顿;不加限制的历史数组越滚越大,匹配效率越来越低。
- 每次新增前先
filter去重:history = [...new Set([...history, keyword])] - 限定最多存 10 条:
history = history.slice(-10) - 存取用
uni.setStorage/uni.getStorage,别直接操作localStorage(H5 可用,但 App 和小程序不兼容) - 读取历史建议放在页面 onShow 阶段,而非 onLoad,避免首次加载过慢影响首屏
fetchSuggestions 内部加个简单的 abort controller 或标记字段,确保只处理最新一次请求的响应。


















