如何在类Web开发范式中进行状态持久化?

简介: 如何在类Web开发范式中进行状态持久化?

在类Web开发范式(.hml/.css/.js)中,状态持久化指将应用的关键数据(如用户登录信息、设置偏好、缓存内容等)保存到本地存储,确保应用重启或页面刷新后数据不丢失。鸿蒙提供了多种本地存储API,可根据数据特性选择合适的方案,以下是具体实现方式:

一、常用存储方案及适用场景

鸿蒙类Web开发范式支持3种核心本地存储方式,各有特点:

存储方式 数据类型 容量限制 适用场景
Preferences 键值对(基本类型) 单键值≤4KB,总容量≤128KB 轻量配置(如主题设置、登录状态)
LocalStorage 键值对(字符串) 约5MB 页面级缓存(如表单草稿、列表滚动位置)
File 任意数据(二进制/文本) 无限制(取决于设备存储) 大量数据(如离线文件、图片缓存)

二、具体实现方式

1. Preferences(推荐:轻量键值对存储)

Preferences是鸿蒙提供的轻量级键值存储,适合保存配置类数据,支持同步/异步操作,数据持久化到应用沙箱目录。

初始化与获取实例

import preferences from '@ohos.data.preferences';

// 获取Preferences实例(参数为文件名,同一应用内可通过文件名区分不同存储)
let pref;
async function getPreferences() {
   
  if (!pref) {
   
    pref = await preferences.getPreferences(this.context, 'app_config');
  }
  return pref;
}

存储数据(异步)

// 保存用户登录状态
async function saveLoginState(isLogin, userInfo) {
   
  const pref = await getPreferences();
  // 支持string/number/boolean等基本类型
  await pref.put('isLogin', isLogin);
  await pref.put('userName', userInfo.name);
  await pref.put('userId', userInfo.id);
  // 必须调用flush()才会真正写入磁盘
  await pref.flush();
}

读取数据(异步)

// 读取登录状态
async function getLoginState() {
   
  const pref = await getPreferences();
  // 第二个参数为默认值(若key不存在则返回)
  const isLogin = await pref.get('isLogin', false);
  const userName = await pref.get('userName', '');
  return {
    isLogin, userName };
}

删除数据

async function clearLoginState() {
   
  const pref = await getPreferences();
  await pref.delete('isLogin');
  await pref.delete('userName');
  await pref.flush();
}

2. LocalStorage(页面级存储,会话级持久化)

LocalStorage是基于页面上下文的存储,数据以字符串形式保存,适合单页面内的临时缓存(应用重启后数据可能丢失,不同页面间不共享)。

使用示例

// 保存表单草稿(同步操作)
saveFormDraft(formData) {
   
  // 需将对象转为字符串(LocalStorage仅支持字符串值)
  localStorage.setItem('formDraft', JSON.stringify(formData));
}

// 读取表单草稿
getFormDraft() {
   
  const draftStr = localStorage.getItem('formDraft');
  return draftStr ? JSON.parse(draftStr) : {
   };
}

// 删除草稿
clearFormDraft() {
   
  localStorage.removeItem('formDraft');
  // 或清空所有数据:localStorage.clear();
}

注意

  • LocalStorage数据与页面绑定,页面销毁后可能被回收,不适合长期存储。
  • 数据大小建议控制在5MB以内,避免影响页面性能。

3. File(文件存储,适合大量/复杂数据)

当需要存储大量数据(如离线数据库、图片缓存、复杂JSON)时,可使用文件存储API,直接操作应用沙箱内的文件。

保存JSON数据到文件

import fileio from '@ohos.fileio';
import featureAbility from '@ohos.ability.featureAbility';

// 获取应用沙箱目录(文档目录,数据会持久化)
async function getDocDir() {
   
  const context = featureAbility.getContext();
  return await context.getFilesDir();
}

// 保存复杂数据到文件
async function saveLargeData(data) {
   
  const docDir = await getDocDir();
  const filePath = `${
     docDir}/large_data.json`;
  // 将对象转为字符串
  const content = JSON.stringify(data);

  // 写入文件(覆盖模式)
  const fd = fileio.openSync(filePath, 0o2 | 0o100, 0o666); // 0o2表示写入,0o100表示创建文件
  fileio.writeSync(fd, content);
  fileio.closeSync(fd);
}

从文件读取数据

async function readLargeData() {
   
  try {
   
    const docDir = await getDocDir();
    const filePath = `${
     docDir}/large_data.json`;

    // 读取文件内容
    const fd = fileio.openSync(filePath, 0o1); // 0o1表示只读
    const buffer = new ArrayBuffer(4096); // 缓冲区大小
    const readSize = fileio.readSync(fd, buffer);
    fileio.closeSync(fd);

    // 转换为字符串并解析JSON
    const content = String.fromCharCode.apply(null, new Uint8Array(buffer.slice(0, readSize)));
    return JSON.parse(content);
  } catch (e) {
   
    // 文件不存在时返回默认值
    return {
    list: [] };
  }
}

三、状态持久化最佳实践

  1. 选择合适的存储方案

    • 配置类数据(如主题、是否自动登录)→ Preferences
    • 页面临时缓存(如表单草稿)→ LocalStorage
    • 大量/复杂数据(如离线列表、图片)→ File
  2. 数据序列化与加密

    • 存储对象/数组时,需通过JSON.stringify()转为字符串,读取时用JSON.parse()还原。
    • 敏感数据(如用户token、手机号)建议加密后存储(可使用鸿蒙提供的@ohos.security.crypto模块)。
  3. 避免频繁写入

    • Preferences的flush()操作是异步写入磁盘,频繁调用会影响性能,建议合并多次更新后再调用。
    • 例如:用户修改多个设置项时,全部修改完成后再执行一次flush()
  4. 清理过期数据

    • 定期清理不再需要的存储(如缓存的临时图片、过期的会话信息),避免占用过多存储空间。
    • 可在应用启动时检查数据时间戳,删除超过有效期的数据。
  5. 错误处理

    • 存储操作可能因权限、磁盘空间不足等失败,需添加try/catch捕获异常,确保应用稳定性。

总结

类Web开发范式中,状态持久化主要通过Preferences(轻量键值)、LocalStorage(页面缓存)和File(大量数据)实现,核心是根据数据特性选择合适的存储方案,并做好序列化、加密和错误处理。对于大多数场景,Preferences是性价比最高的选择,既能保证数据持久化,又能兼顾性能和易用性。

相关文章
|
5月前
|
人工智能 边缘计算 自然语言处理
|
6月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
5月前
|
前端开发 Java 测试技术
Playwright 自动化测试系列(7)| 第三阶段:测试框架集成​​Page Object 模式
Page Object模式通过封装页面元素与操作,提升测试代码的可维护性、可读性与复用性,助力构建高效稳定的电商自动化测试框架。
|
6月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
289 1
|
11月前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
684 17
|
监控 测试技术 Docker
【步步惊心】Flask应用云端之旅:从本地调试到一键上线的终极秘籍!
【8月更文挑战第31天】本文详细介绍了将基于Flask框架的Web应用从本地开发环境部署到云平台的全过程。首先,通过示例代码展示了如何搭建本地环境并测试应用。接着,讲解了如何使用Docker构建生产环境镜像。最后,以Heroku为例,说明了如何将应用部署到云平台,并介绍了监控与维护的方法。通过本文的最佳实践,你可以轻松完成Flask应用的部署。
416 0
|
11月前
|
Kubernetes Java 持续交付
小团队 CI/CD 实践:无需运维,Java Web应用的自动化部署
本文介绍如何使用GitHub Actions和阿里云Kubernetes(ACK)实现Java Web应用的自动化部署。通过CI/CD流程,开发人员无需手动处理复杂的运维任务,从而提高效率并减少错误。文中详细讲解了Docker与Kubernetes的概念,并演示了从创建Kubernetes集群、配置容器镜像服务到设置GitHub仓库Secrets及编写GitHub Actions工作流的具体步骤。最终实现了代码提交后自动构建、推送镜像并部署到Kubernetes集群的功能。整个过程不仅简化了部署流程,还确保了应用在不同环境中的稳定运行。
630 9
|
设计模式 安全 数据库连接
【C++11】包装器:深入解析与实现技巧
本文深入探讨了C++中包装器的定义、实现方式及其应用。包装器通过封装底层细节,提供更简洁、易用的接口,常用于资源管理、接口封装和类型安全。文章详细介绍了使用RAII、智能指针、模板等技术实现包装器的方法,并通过多个案例分析展示了其在实际开发中的应用。最后,讨论了性能优化策略,帮助开发者编写高效、可靠的C++代码。
339 2
|
容器
echarts的grid——图表的位置配置
echarts的grid——图表的位置配置
2412 1
|
弹性计算
阿里云账号注册流程图文详解、账户实名认证和申请免费服务器全流程
阿里云账号注册支持手机号、支付宝等验证方式。使用手机号需手动验证,而支付宝等可自动完成实名认证。注册后须进行个人或企业实名认证才能正常使用服务。个人认证推荐使用支付宝快速完成;企业认证也支持支付宝法人扫描完成。完成认证后,可在免费中心申请最长达3个月的免费服务器试用,或选择付费方案获得更多资源。