微博式话题选择必须用 scroll-view + 动态渲染实现,因 uni-data-picker 和原生 picker 无法支持搜索驱动的动态树形选择、多级中途确认及语义聚类分组;需手动管理展开状态、防抖搜索、请求取消与去重逻辑。

直接用 uni-data-picker 或原生 picker 做不了——微博那种“输入关键词→动态联想→多级点击展开→支持任意层级中途确认”的交互,本质是「搜索驱动的树形选择器」,不是静态级联。
为什么不能用 mode="region" 或 uni-data-picker 的 lazy-load
前者只认省市区三级且字段写死;后者依赖完整树结构预加载或逐层请求,而微博话题是「扁平标签池 + 动态聚类」:用户输“AI”,后端返回 [ { name: "AI工具", children: ["Cursor", "Claude"] }, { name: "AI绘画", children: ["Midjourney", "DALL·E"] } ],这不是固定层级,是按语义聚类的临时分组。
-
uni-data-picker要求数据必须是严格嵌套树,children 不能为空数组,但联想结果里每个分组的子项可能随时为空 - 它不支持「输入框内实时触发联想 + 点击分组标题展开子项 + 子项可直接选中」这个混合流程
- bindchange 只在 picker 确认后触发,无法响应中间点击行为
必须用 scroll-view + 动态渲染 + 手动状态管理
核心思路:放弃 picker 组件,用 scroll-view 滚动容器 + v-for 渲染联想结果,靠 input 的 @input 触发搜索,靠点击事件控制展开/选中。
- 输入框绑定
v-model="searchKey",加@input="debounceSearch"防抖(300ms) - 搜索接口返回结构类似:
[{ group: "编程语言", items: ["JavaScript", "TypeScript"] }, { group: "框架", items: ["Vue", "React"] }] - 每个分组用
<view>...</view>控制expanded[index]开关 - 选中时直接 push 到
selectedTopics,不依赖 value 数组或索引映射 - 注意:iOS 上
scroll-view滚动卡顿?加enhanced="true"和scroll-with-animation
如何处理“多级中途确认”和去重逻辑
微博式话题选择允许用户点“AI工具”就确认整组,也允许点进“AI工具”再选“Cursor”——这需要两层状态:已选中的具体项(selectedItems),和已折叠/展开的分组(expanded)。
- 点击分组标题:若未展开,请求该分组下钻数据(如“AI工具”→查子标签);若已展开,直接收起
- 点击子项:
selectedItems.push(item),同时检查是否已存在相同item.id,避免重复添加 - 回删某一项:用
selectedItems.findIndex找索引并splice,不要用 filter —— 会破坏顺序且无法响应 v-model - H5 端需额外处理:禁用原生 input 的 autocomplete,防止浏览器填充干扰联想
最易被忽略的是搜索防抖与请求取消:用户快速输入“AI绘”,可能发出 “AI”、“AI绘” 两个请求,后一个先返回就会覆盖前一个的展开状态。必须用 AbortController 或标记当前有效 requestID,在响应到达时校验是否仍为最新请求。










