应监听@input事件,用/#1*$/正则检测未闭合话题并提取关键词,过滤空输入,移动端需处理composition事件;下拉面板须用绝对定位scroll-view实现;插入话题后需手动控制光标位置;uni-search-bar不适用因无法获取光标状态且逻辑冲突。# ↩

话题输入框怎么监听#号触发搜索
不能等用户输完两个#才响应,得在第一个#按下时就启动搜索流程。关键点是监听 @input 事件,用正则检测末尾是否为 # 或 #关键词 形式,而不是等完整闭合。
- 错误做法:只匹配
/#(.*?)#/g—— 这要求用户已输入完整话题,无法支持“边输边搜” - 正确做法:用
/#[^#]*$/检测光标前未闭合的话题,提取#AI中的AI部分作为搜索关键词 - 需过滤空输入:
#、#、#(全角空格)都应忽略,避免发空请求 - 移动端要注意
compositionstart/compositionend事件,防止中文输入法中途触发误搜
多级搜索结果怎么动态渲染进输入框下方
不能直接用 picker 或 uni-popup 堆叠弹层——它们不支持嵌套滚动+焦点穿透,且 iOS 下常被键盘顶飞。必须用绝对定位 + scroll-view 自建下拉面板。
- 容器需设
position: absolute; top: 100%; z-index: 999;,并绑定v-show控制显隐 - 每个候选话题用
<view class="topic-item"></view>,不要用button(小程序里 button 会抢 focus) - 滚动区域加
enhanced="true"和show-scrollbar="false",避免 H5 端滚动条干扰视觉 - 真机调试时,Android 需加
style="height: 200rpx;"固定高度,否则scroll-view可能撑不开
插入话题后如何保持光标在正确位置
直接 v-model 拼接字符串会导致光标跳到末尾,必须手动控制光标位置。uni-app 没有原生 setSelectionRange 支持,得靠 textarea 的 focus + uni.createSelectorQuery 补位。
- 先用
this.$nextTick(() => { this.$refs.textarea.focus() })激活输入框 - 再用
uni.createSelectorQuery().select('#myTextarea').boundingClientRect(res => {...})获取光标偏移 - 计算新文本长度差值,调用
textarea.setSelectionRange(start, end)(仅 App 和 H5 支持,小程序需降级为光标置尾) - 若插入的是
#AI#,光标应落在第二个#后,而非整个字符串末尾
为什么不能用 uni-search-bar 做话题搜索框
uni-search-bar 是单层搜索组件,设计目标是“关键词→结果页”,不是“嵌入式话题补全”。强行套用会踩三个硬坑:
- 它内部封装了
input,无法暴露光标位置和输入状态,你拿不到#AI这种未闭合片段 - 自带清空按钮和 confirm 逻辑,会干扰话题输入流程(比如用户想输
#AI#,点清空却删掉整个内容) - 样式深度绑定,想改 placeholder 颜色或搜索图标位置得重写 whole component,不如从
input重搭
真正要复用的是它的防抖逻辑和历史记录管理能力,而不是 UI 组件本身。










