热搜需服务端推送+前端渐进式刷新:全量接口/api/hotlist首次加载,增量接口/api/hotlist/delta仅更新变动项;禁用轮询,改用onAppShow/visibilitychange触发检查;delta带timestamp防乱序;点击高亮词后需uni.$nextTick聚焦并confirm;排序依赖rank字段,高亮加key强制重渲染;历史记录统一normalize去重、分key存储;输入中冻结原数据防清空。

热搜列表怎么实时更新又不卡顿
直接轮询接口或 onShow 里反复拉取,会导致页面白屏、CPU 占用飙升,尤其在低端安卓机和微信小程序上明显。必须把「实时性」和「性能」拆开处理:趋势变化靠服务端推送(如 WebSocket),前端只做「渐进式刷新」+「本地缓存兜底」。
- 后端提供两个接口:
/api/hotlist(全量)、/api/hotlist/delta(增量 diff),后者返回 { id: '1024', rank: 3, delta: -1 } 这类结构,前端只 patch 变动项 - 前端禁用
setInterval轮询;改用uni.onAppShow+ 页面 visibilitychange 监听,仅在用户切回前台时触发一次检查 - 首次加载用
onLoad预拉全量,后续更新走 delta 接口,避免重复渲染整个列表 - delta 响应里带
timestamp,若与本地时间差 > 60s,直接丢弃,防止网络抖动导致乱序
点击热搜词后输入框光标丢失怎么办
这是 Vue2 响应式 + uni-search-bar 的经典兼容问题:赋值 this.keyword = item.name 后 DOM 未重绘完成,focus() 就失效了。iOS 小程序尤其严重。
- 必须加
uni.$nextTick(不是this.$nextTick,uni-app 2.x 全局 API)再调用聚焦 - 不要用
@click直接触发搜索,先设值、再 nextTick、再手动 focus、最后 confirm —— 四步缺一不可 - 示例代码:
clickTab(item) { this.keyword = item.name; uni.$nextTick(() => { const searchBar = this.$refs.searchBarRef; if (searchBar && searchBar.focus) { searchBar.focus(); // 确保输入框内容已同步 setTimeout(() => { searchBar.confirm(); }, 100); } }); }
热门词高亮和排序逻辑怎么写才不翻车
单纯按接口返回顺序渲染,遇到「上升最快」「热度峰值」这类业务指标时会错乱。前端必须保留原始 rank 字段,并用它控制视觉权重,而不是依赖数组下标。
- 后端返回的每个热搜项必须含
rank(当前排名)、prev_rank(上期排名)、hot_value(热度分),三者缺一不可 - 前端用
rank控制v-for渲染顺序,用prev_rank - rank计算箭头方向(↑↓→),禁止用 index 做判断 - 高亮不能只靠
:class="{ active: keyword === item.name }",要加:key="item.id + '_' + item.rank"强制重渲染,否则 iOS 下点击后样式残留 - 热度色阶用 CSS 变量动态绑定:
:style="{ '--hot-color': getHotColor(item.hot_value) }",避免内联 style 大量重复计算
历史记录和热搜共存时怎么避免冲突
用户点热搜词后,既要填入输入框,又要加到历史记录,但 uni.setStorageSync 是同步阻塞操作,高频点击可能造成历史列表错位或丢失。
- 历史记录上限固定为 10 条,每次新增先用
unshift()插入头部,再用splice(10)截断,别用 filter 去重——全半角空格、大小写差异必须统一 normalize - 去重逻辑必须提前做:
const normalized = keyword.trim().replace(/[\uFEFF\u200B-\u200D\u2060\uFEFF]/g, ''),清除零宽字符 - 热搜词和历史记录使用不同 storage key:
uni.setStorageSync('search_hot_cache', list)和uni.setStorageSync('search_history', list),避免互相覆盖 - App 端注意:
uni.setStorageSync在 Android 上可能触发磁盘 IO 延迟,建议加 try/catch 包裹,失败时降级为内存暂存
真实场景里最易被忽略的是「热搜数据冻结时机」:用户正在输入时,后台推送新榜单,如果直接替换 hotList,会导致正在输入的关键词被意外清空。得用 Object.freeze() 锁定原始数据,新榜用独立变量暂存,等用户离开搜索页再合并。


















