uni.setstoragesync存数组必须先json.stringify,读取时用json.parse并兜底空数组;去重置顶需findindex+splice+unshift;onshow同步历史更可靠;清空历史须setstoragesync空数组而非removestoragesync。

uni.setStorageSync 存数组前必须 JSON.stringify
直接 uni.setStorageSync('searchHistory', this.historyList) 会静默失败——它只接受字符串,传数组进去不报错但读出来是 undefined 或空字符串。真正能落地的写法是:uni.setStorageSync('searchHistory', JSON.stringify(this.historyList))。读取时也得配套处理:const list = JSON.parse(uni.getStorageSync('searchHistory') || '[]'),|| '[]' 是为了兜底 getStorageSync 返回 null 或 undefined 的情况,否则 JSON.parse(null) 直接崩。
去重 + 置顶必须先 findIndex 再 splice + unshift
用户搜 “iPhone” → “Android” → 再搜 “iPhone”,理想效果是 “iPhone” 回到第一位,“Android” 往后排。如果每次无脑 unshift,就会重复。正确流程是:
- 用
history.findIndex(item => item.toLowerCase() === keyword.toLowerCase())查旧位置 - 查到了就
history.splice(index, 1)删掉旧记录 - 再
history.unshift(keyword)插入开头 - 最后
history.slice(0, 10)截取前 10 条,避免膨胀
别用 filter 或 Array.from(new Set()),前者破坏顺序,后者打乱原有时间序。
onShow 比 onLoad 更适合同步历史列表
onLoad 只在页面首次加载时触发,而搜索页常被反复进出(比如从结果页返回),这时历史列表可能已被其他操作清空或更新,onLoad 不会再次执行。推荐在 onShow 中读取并赋值:this.historyList = JSON.parse(uni.getStorageSync('searchHistory') || '[]')。如果页面带默认关键词等参数,可在 onLoad 初始化,onShow 负责同步缓存状态。
清空历史必须 setStorageSync 空数组,不是 removeStorageSync
只调 uni.removeStorageSync('searchHistory') 是不够的:后续 JSON.parse(uni.getStorageSync('searchHistory')) 会因返回 null 报错;而且 Vue2 在 H5/APP 环境下对空数组响应不敏感,UI 常卡住不动。安全清空必须两步走:
this.historyList = []uni.setStorageSync('searchHistory', JSON.stringify([]))
如果用了 computed 包装历史列表,记得清空后手动赋值,否则 getter 仍返回旧引用。
最易被忽略的是大小写归一化比对和读取时的默认值兜底——它们不会立刻报错,但会让历史记录看起来“时灵时不灵”。











