【鸿蒙实战开发】记录下LocalStorage、AppStorage、PersistentStorage的持久化存储相关

前言

记录下最近适配鸿蒙用到状态存储的一些理解。

理解

虽然官方文档中将管理应用存储分为了LocalStorage(页面级)、AppStorage(应用级)、PersistentStorage(持久化存储)三种类型。
使用下来,感觉其实只要关注LocalStorage(页面级)、AppStorage(应用级)两种类型就好了,而PersistentStorage与其说是存储管理,不如说是存储标记,具体的看下问吧。

LocalStorage页面级存储

在鸿蒙中LocalStorage从概念和理解是都完全不同于 Web的 localStorage。他相当于设置了一个只作用于某个页面的存储区。
别看官方文档写了一大堆,实际上用法无外乎以下:

●声明:new LocalStorage(object) ,创建一个LocalStorage,可以设置初始内容。
●绑定到页面:在 页面的组件 上使用 @Entry(storage)进行绑定。绑定后,该页面组件、以及子组件都可使用该存储中的数据了。
●使用:

○@LocalStorageProps:单向绑定,也就是页面改变了值的内容,不会影响到 localStore 中存储数据
○@LocalStorageLink:双向绑定,也就是页面改变了值的内容,会一并影响到 localStore 中存储数据
○PS: 值得一提的是,鸿蒙中@Props 都是单向绑定,@Link 都是双向绑定。

  //初始化
 let para: Record<string, number> = { 'PropA': 47 };
 let storage: LocalStorage = new LocalStorage(para);
 
 //添加创建值
 storage.setOrCreate('PropB', new PropB(50));

 //绑定
 @Entry(storage)
 @Component
struct CompA {

   //使用
   @LocalStorageProps('PropA') childLinkNumber: number = 1;
   @LocalStorageLink('PropB')
### 关于 `localStorage.getItem` 方法不存在的原因分析 如果在浏览器中发现 `localStorage.getItem` 方法不存在的情况,可能是由于以下几个原因: 1. **无痕模式的影响** 部分浏览器(如UC浏览器)在无痕模式下禁用了 `localStorage` 功能[^2]。在这种情况下,即使尝试调用 `localStorage.getItem` 或其他相关方法也会失败。 2. **浏览器兼容性问题** 虽然大多数现代浏览器都支持 HTML5 的 `localStorage` 特性,但在某些老旧版本的浏览器中可能不完全支持该功能。可以使用以下代码检测当前环境是否支持 `localStorage`: ```javascript function isLocalStorageSupported() { try { const testKey = 'test'; localStorage.setItem(testKey, null); localStorage.removeItem(testKey); return true; } catch (e) { return false; } } if (!isLocalStorageSupported()) { console.error('Local Storage 不被支持'); } ``` 3. **安全策略限制** 如果页面运行在一个受限的安全环境中(例如沙盒化的 iframe),可能会导致 `localStorage` API 被禁用。这种情况下,任何对 `localStorage` 的访问都会抛出异常或返回未定义的结果。 4. **脚本错误覆盖原生方法** 可能存在第三方库或其他脚本意外重写了全局对象中的 `localStorage` 属性或其方法。可以通过以下方式验证原始方法是否存在: ```javascript if (typeof window.localStorage !== 'object' || typeof window.localStorage.getItem !== 'function') { console.error('localStorage 或 getItem 方法已被修改或不可用'); } ``` 5. **缓存清除操作** 用户手动清除了浏览器缓存或者通过开发者工具删除了所有的本地存储数据,这可能导致误以为 `getItem` 方法失效。实际上这是正常的预期行为,因为当指定键名的数据不存在时,`getItem` 返回的是 `null`。 --- ### 解决方案 针对上述情况,以下是几种可行的解决方案: #### 方案一:切换到正常浏览模式 对于因启用无痕模式而导致的功能缺失,建议用户关闭无痕模式或将数据保存逻辑迁移到 `sessionStorage` 或者 Cookies 中去实现。 #### 方案二:降级处理机制 为了应对不同设备上的差异表现,在实际开发过程中应该设计合理的回退计划。比如优先尝试利用 `localStorage` 来完成任务;一旦发现问题,则改用 Cookie 替代: ```javascript function setItem(key, value) { if (isLocalStorageSupported()) { localStorage.setItem(key, JSON.stringify(value)); } else { document.cookie = `${key}=${encodeURIComponent(JSON.stringify(value))}; path=/`; } } function getItem(key) { if (isLocalStorageSupported()) { return JSON.parse(localStorage.getItem(key)); } else { const cookies = document.cookie.split('; '); for (let cookie of cookies) { let [name, val] = cookie.split('='); if (name === key) { return JSON.parse(decodeURIComponent(val)); } } return null; } } ``` #### 方案三:增强健壮性的封装函数 创建统一接口来管理所有类型的持久化需求,并自动适配最佳可用选项。 ```javascript class PersistentStorage { constructor(storageType='local'){ this.storage = storageType==='local'?window.localStorage:window.sessionStorage; } saveData(key,value){ if(this.isAvailable()){ this.storage.setItem(key,JSON.stringify(value)); }else{ throw new Error("Persistent storage unavailable"); } } loadData(key){ if(this.isAvailable()){ return JSON.parse(this.storage.getItem(key)); } return undefined; } removeData(key){ if(this.isAvailable()){ this.storage.removeItem(key); } } clearAll(){ if(this.isAvailable()){ this.storage.clear(); } } isAvailable(){ try{ const testKey="availabilityTest"; this.storage.setItem(testKey,"true"); this.storage.removeItem(testKey); return true; }catch(e){ return false; } } } const persistentStore=new PersistentStorage(); // 默认采用 local storage persistentStore.saveData("username","JohnDoe"); console.log(persistentStore.loadData("username")); // 输出 JohnDoe ``` --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值