当前位置: 首页 > news >正文

HarmonyOS 6商城开发学习:商品浏览记录本地存储——PersistentStorage+AppStorage驱动去重与上限截断

在HarmonyOS 6购物比价或电商类应用中,"最近浏览"是高频场景:用户进入商品详情页,自动将商品追加到浏览记录列表(去重、上限保留如20条),我的-浏览历史页按时间倒序展示,支持清空。记录只需存本地,不需要账号云同步。

官方行业实践推荐用PersistentStorage 持久化 + AppStorage 响应式驱动,本文将完整实现这一方案——含数据模型、去重截断、历史列表展示与清空。


一、需求拆解与数据模型

1. 功能点

  • 进入商品详情 → 调用addBrowseRecord(goods)→ 同ID去重后置顶、超上限截断 → 自动落盘

  • 浏览历史页 → 从 AppStorage 读取数组 →ForEach渲染卡片

  • 清空 → 置空数组 → 自动同步 PersistentStorage

2. 数据模型

// model/BrowseRecord.ets export interface BrowseGoods { id: string; name: string; price: string; // "¥199" img: Resource; // 缩略图 browseTime: number; // Date.now() 时间戳 } export const MAX_BROWSE = 20; // 最多保留条数 export const STORE_KEY = 'browse_history';

二、持久化初始化(关键一步)

必须在UIAbility 的onWindowStageCreate​ 或入口页aboutToAppear最早时机调用,将 key 与 AppStorage 双向绑定:

// 在 EntryAbility.ets 或首个 Page aboutToAppear 中 import { PersistentStorage } from '@ohos.arkui.node'; // 初始化:若磁盘无值则用 '[]' PersistentStorage.persistProp('browse_history', '[]');

⚠️persistProp(key, defaultValue)只需调用一次/应用生命周期,后续直接用AppStorage.get/set即可自动读写磁盘。


三、浏览记录管理工具类

// utils/BrowseStore.ets import { BrowseGoods, MAX_BROWSE, STORE_KEY } from '../model/BrowseRecord'; /** 读取当前浏览记录(解析JSON) */ export function loadBrowseList(): BrowseGoods[] { try { const raw = AppStorage.get<string>(STORE_KEY) ?? '[]'; return JSON.parse(raw) as BrowseGoods[]; } catch { return []; } } /** 写入并自动持久化 */ function save(list: BrowseGoods[]) { AppStorage.setOrCreate(STORE_KEY, JSON.stringify(list)); // PersistentStorage 监听 AppStorage 变化自动 flush,无需手动调 } /** 添加浏览记录(去重→置顶→截断) */ export function addBrowseRecord(goods: BrowseGoods) { let list = loadBrowseList(); // 去重:移除旧相同ID list = list.filter(i => i.id !== goods.id); // 置顶 list.unshift({ ...goods, browseTime: Date.now() }); // 上限截断 if (list.length > MAX_BROWSE) { list = list.slice(0, MAX_BROWSE); } save(list); } /** 清空浏览记录 */ export function clearBrowseHistory() { save([]); }

四、商品详情页——触发记录(示例)

// pages/GoodsDetailPage.ets import { addBrowseRecord } from '../utils/BrowseStore'; import { BrowseGoods } from '../model/BrowseRecord'; @Entry @Component struct GoodsDetailPage { // 模拟当前商品 private goods: BrowseGoods = { id: 'G007', name: 'HarmonyOS 6 旗舰耳机', price: '¥599', img: $r('app.media.ic_headphone'), browseTime: 0 }; aboutToAppear() { // 进入详情即记录浏览 addBrowseRecord(this.goods); } build() { Column() { Image(this.goods.img).width(200).height(200).objectFit(ImageFit.Contain) .margin(24) Text(this.goods.name).fontSize(18).fontWeight(FontWeight.Bold) Text(this.goods.price).fontSize(16).fontColor('#FF5722').margin(8) Text('已加入浏览记录').fontSize(12).fontColor('#999').margin(40) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .backgroundColor(Color.White) } }

五、浏览历史页——列表展示与清空

// pages/BrowseHistoryPage.ets import { loadBrowseList, clearBrowseHistory } from '../utils/BrowseStore'; import { BrowseGoods } from '../model/BrowseRecord'; import { promptAction } from '@kit.ArkUI'; @Entry @Component struct BrowseHistoryPage { // 用 @State 同步,实际项目可在 aboutToAppear 中 loadBrowseList 初始化 // 若想完全响应式可包装成 @StorageLink('browse_history') 自行解析,此处简化为 onShow 重载 @State list: BrowseGoods[] = []; onShow() { this.list = loadBrowseList(); } build() { Column() { // 标题栏 Row { Text('浏览记录') .fontSize(20) .fontWeight(FontWeight.Bold) Blank() if (this.list.length > 0) { Text('清空') .fontSize(13) .fontColor('#FF5722') .onClick(() => { clearBrowseHistory(); this.list = []; promptAction.showToast({ message: '已清空' }); }) } } .padding({ horizontal: 16, top: 16, bottom: 8 }) // 列表 if (this.list.length === 0) { Column() { Text('暂无浏览记录') .fontSize(14) .fontColor('#BBB') } .layoutWeight(1) .justifyContent(FlexAlign.Center) } else { List() { ForEach(this.list, (item: BrowseGoods) => { ListItem() { Row({ space: 12 }) { Image(item.img) .width(64).height(64).borderRadius(8).objectFit(ImageFit.Cover) Column() { Text(item.name).fontSize(15).fontColor('#333').maxLines(1) Text(item.price).fontSize(14).fontColor('#FF5722').margin({ top: 4 }) Text(formatTime(item.browseTime)) .fontSize(11) .fontColor('#AAA') .margin({ top: 2 }) }.layoutWeight(1).alignItems(HorizontalAlign.Start) } .padding(12) } }, (item: BrowseGoods) => item.id) } .layoutWeight(1) .padding(12) } } .width('100%') .height('100%') .backgroundColor('#F5F6F8') } } // 时间格式化辅助 function formatTime(ts: number): string { if (!ts) return ''; const d = new Date(ts); return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')} ${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}`; }

六、避坑指南

问题

原因

修复

重启后记录丢失

未调PersistentStorage.persistProp()或调太晚(页面已mount)

EntryAbility.onWindowStageCreate最早调一次

存储值变[object Object]

直接AppStorage.set(STORE_KEY, list)JSON.stringify

存字符串化JSON:JSON.stringify(list)

历史页不刷新

onShow未重新loadBrowseList()

onShow中刷新@State list

ForEach key用index

列表重排可能UI异常

key用item.id(唯一商品ID)

超限不截断

unshiftslice(0,MAX)

添加后list = list.slice(0, MAX_BROWSE)


七、总结:浏览记录存储SOP

  1. 初始化PersistentStorage.persistProp('browse_history','[]')应用启动时执行一次

  2. 进入详情addBrowseRecord()→ 去重→置顶→截断→AppStorage.set(字符串化数组)

  3. 历史页onShowloadBrowseList()渲染;清空调clearBrowseHistory()。

  4. PersistentStorage自动落盘:AppStorage值变化即异步写磁盘,无需手动flush。

核心法则:HarmonyOS 6本地浏览记录 =PersistentStorage绑定AppStorage + JSON序列化数组 + 去重置顶截断,轻量、响应、无服务端依赖。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任。

http://www.zskr.cn/news/1487271.html

相关文章:

  • 2026真空绝热板行业深度:能效新国标倒逼百亿市场洗牌,五家核心制造商技术实力与服务能力横向拆解 - 品研笔录
  • 如何快速获取中小学智慧教育平台电子课本的PDF文件
  • 钦州市黄金回收白银回收铂金回收攻略,实地甄选五家优质实体店 - 诚金汇钻回收公司
  • DiffSinger:基于浅层扩散机制的高保真歌唱语音合成系统
  • 2026年PDF解密软件主流厂商横评:如何选合适的服务商 - 资讯速览
  • 5分钟彻底告别风扇噪音:Windows免费风扇控制神器完全指南
  • MPC8xx嵌入式系统SDRAM接口设计与UPM编程实战指南
  • 2026龙岩市黄金回收白银回收铂金回收怎么变现?实地探访 5 家本地老牌回收店铺 - 中安检金银铂钻回收
  • 八、shell脚本
  • 056、训练引擎 Model.train 源码逐行解析:从入口函数到反向传播的调用链路
  • 终极免费方案:3分钟永久解锁IDM下载加速功能
  • 六盘水市黄金回收白银回收铂金回收实测 + 5 家正规线下门店盘点 - 信誉隆金银铂奢回收
  • 建筑三维动画制作公司怎么选?五个关键指标帮你避坑
  • 终极免费方案:如何一键解锁八大网盘全速下载新时代
  • 2026巴中市黄金回收白银回收铂金回收怎么变现?实地探访 5 家本地老牌回收店铺 - 中安检金银铂钻回收
  • HCS12软件站实战:从零搭建嵌入式开发框架与串口通信项目
  • 网盘直链下载终极指南:突破限速的专业解决方案
  • OpenClaw强大的 Skill 技能扩展能力|15个高频自动化技能提升办公效率
  • EP4CE6 FPGA数字钟工程包:含整点蜂鸣、数码管显示与完整Quartus II编译文件
  • Apple Cursor:为Windows和Linux系统带来macOS优雅光标体验的完整指南
  • 如何构建个人AI数据资产:WeChatMsg微信聊天记录本地化与数据分析实战指南
  • 固原市黄金回收白银回收铂金回收实测 + 5 家正规线下门店盘点 - 信誉隆金银铂奢回收
  • 2026年大连工程家具定制与全屋定制深度横评:源头工厂直营vs传统门店的真实对比指南 - 精选优质企业推荐官
  • Playnite终极指南:如何一站式管理20+游戏平台与模拟器库
  • 深度架构解析:构建高性能流媒体平台的技术方案
  • FCPBGA与FCCSP封装实战指南:从PCB设计到焊接工艺全解析
  • ok-ww:基于图像识别的鸣潮自动化工具技术解析与应用指南
  • nhentai跨平台漫画阅读器终极指南:打造全平台无缝阅读体验
  • 杭州手表回收行情解析 收的顶是本地实力代表 - 奢侈品回收评测
  • 嵌入式系统空白Flash启动难题:硬件重映射与软件编程方案解析