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

HarmonyOS 全局状态管理实战:GlobalContext 跨页面数据共享完全指南

文章目录

    • 前言
      • GlobalContext 是什么
      • 写入:put 和 setObject
      • 读取:get 和 getObject
      • has:检查 Key 是否存在
      • remove:移除指定 Key
      • clear:清空所有缓存
      • 综合演示:模拟登录状态管理
      • GlobalContext vs AppStorage:怎么选
      • 写在最后

前言

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓

写 HarmonyOS App,很快就会遇到一个问题:登录成功后,token 存在哪,其他页面怎么拿?

路由传参只能传一次,AppStorage有绑定 UI 的额外开销,很多时候你就想要个简单的"全局 HashMap"——存进去,随时取,谁都能用。

GlobalContext就是这个东西。

GlobalContext 是什么

GlobalContext是一个应用级别的单例 Key-Value 缓存,本质上就是一个Map<string, Object>

它的特点:

  • 单例:整个应用只有一个实例,所有页面共享
  • 类型安全:支持泛型取值,取出来的类型可以直接用
  • 轻量:没有响应式、没有 UI 绑定,就是纯粹的键值存储

演示代码里的描述:

Column({space:4}){Text('GlobalContext 是应用全局单例 Key-Value 缓存').fontSize(13).fontColor('#555')Text('支持跨页面、跨组件传递任意 Object 数据').fontSize(12).fontColor('#888')}

写入:put 和 setObject

// put:写入任意类型GlobalContext.getContext().put(this.inputKey,this.inputValue);this.addLog(`put("${this.inputKey}", "${this.inputValue}")`);// setObject:功能一样,名字不同GlobalContext.getContext().setObject(this.inputKey,this.inputValue);this.addLog(`setObject("${this.inputKey}", "${this.inputValue}")`);

putsetObject功能完全等同,语义略有差别,按习惯选一个用就好。

写入数字类型

GlobalContext.getContext().put('timestamp',Date.now());this.addLog(`put("timestamp",${Date.now()})`);

写入对象类型

// 先定义 interfaceinterfaceUserInfo{name:string;age:number;roles:string[];}// 再写入constobj:UserInfo={name:'若城',age:18,roles:['admin','user']};GlobalContext.getContext().put('userInfo',obj);this.addLog(`put("userInfo",${JSON.stringify(obj)})`);

GlobalContext 的值类型是Object,所以可以存任意类型。

读取:get 和 getObject

// get<T>:泛型取值,返回 T 类型constval=GlobalContext.getContext().get<string>(this.inputKey);this.getResult=val!==undefined?String(val):'(undefined)';this.addLog(`get("${this.inputKey}") →${this.getResult}`);// getObject:不带泛型,返回 Objectconstval=GlobalContext.getContext().getObject(this.inputKey);this.addLog(`getObject("${this.inputKey}") →${val!==undefined?String(val):'undefined'}`);

get<T>带泛型更推荐,因为取出来的值直接是对应类型,不需要强转。

取数字:

constts=GlobalContext.getContext().get<number>('timestamp');this.addLog(`get<number>("timestamp") →${ts}`);

取对象:

constinfo=GlobalContext.getContext().get<object>('userInfo');this.addLog(`get("userInfo") →${info?JSON.stringify(info):'undefined'}`);

注意:如果 key 不存在,get返回undefined使用前要判断是否 undefined,不然直接访问属性会空指针崩溃。

has:检查 Key 是否存在

constresult=GlobalContext.getContext().has(this.inputKey);this.hasResult=result?'存在':'不存在';this.addLog(`has("${this.inputKey}") →${result}`);// 检查不存在的 keyconstr=GlobalContext.getContext().has('notExistKey');this.addLog(`has("notExistKey") →${r}`);// 结果:false

在读取数据前,用has判断 key 是否存在是个好习惯:

if(GlobalContext.getContext().has('token')){consttoken=GlobalContext.getContext().get<string>('token');// 安全使用 token}

remove:移除指定 Key

// 移除单个 keyGlobalContext.getContext().remove(this.inputKey);this.addLog(`remove("${this.inputKey}") 已移除`);// 移除后验证GlobalContext.getContext().remove(this.inputKey);constr=GlobalContext.getContext().has(this.inputKey);this.addLog(`remove后 has("${this.inputKey}") →${r}`);// 结果:false

clear:清空所有缓存

GlobalContext.getContext().clear();this.addLog('clear() 已清空所有缓存');// 清空后验证GlobalContext.getContext().clear();constr1=GlobalContext.getContext().has(this.inputKey);constr2=GlobalContext.getContext().has('userInfo');this.addLog(`clear后 has("${this.inputKey}") →${r1}`);this.addLog(`clear后 has("userInfo") →${r2}`);// 结果都是 false

clear适合在退出登录时调用,一次性清除所有用户相关的全局状态。

综合演示:模拟登录状态管理

演示代码里有一段完整的登录状态模拟,非常实用:

模拟登录后存储数据

GlobalContext.getContext().put('isLogin',true);GlobalContext.getContext().put('token','Bearer eyJhbGci.example');GlobalContext.getContext().put('userName','全栈若城');GlobalContext.getContext().put('userId',10086);this.addLog('已存储登录信息: isLogin/token/userName/userId');

模拟其他页面读取登录状态

constisLogin=GlobalContext.getContext().get<boolean>('isLogin');constname=GlobalContext.getContext().get<string>('userName');constid=GlobalContext.getContext().get<number>('userId');this.addLog(`isLogin:${isLogin}name:${name}userId:${id}`);

模拟退出登录

GlobalContext.getContext().clear();constisLogin=GlobalContext.getContext().get<boolean>('isLogin');this.addLog(`退出后 isLogin:${isLogin}`);// 结果:undefined

这三步代码展示了 GlobalContext 的完整生命周期:登录存数据、使用时读数据、退出时清数据。

GlobalContext vs AppStorage:怎么选

特性GlobalContextAppStorage
响应式
UI 双向绑定
轻量级
适合存非 UI 数据不推荐
适合存 token、userId一般用全局变量

简单原则:需要 UI 自动更新的数据用@State/AppStorage,不需要 UI 响应的全局数据(token、配置、用户信息)用GlobalContext

写在最后

GlobalContext 的 API 很简单,就四组:

  • put/setObject:写数据
  • get<T>/getObject:读数据,推荐用泛型版
  • has:判断 key 是否存在
  • remove/clear:删除单个或全部

适合存的东西:token、用户 ID、全局配置、应用上下文对象。不适合存的:需要 UI 响应的状态数据(那个用@StateAppStorage)。

http://www.gsyq.cn/news/1417071.html

相关文章:

  • STM32入门实战:从零开始用STM32CubeIDE实现LED闪烁
  • 别再手动移植算法了!保姆级教程:用MATLAB Coder App把.m文件一键转成C静态库
  • 从一次线上宕机复盘说起:我是如何用JMeter压测,定位到RT暴增和QPS暴跌的罪魁祸首
  • 咸阳华帝热水器燃气灶维修|秦都渭城世纪大道上门检修 - GrowthUME
  • 保姆级教程:手把手教你搞定Windows 10/11的远程开机(WOL),告别办公室加班
  • 047、直播录制丢帧、音画不同步?实时 TS 切片写入、Buffer 缓冲与降级策略
  • 咸阳万家乐热水器燃气灶壁挂炉故障维修 咸阳上门服务 - GrowthUME
  • 深度优化gbt7714-bibtex-style的arXiv预印本引用配置方案
  • 2026亲测10款AI智能降重工具红黑榜!优缺点全曝光,达标率对标顶级水准 - 降AI小能手
  • 3步搞定有道云笔记本地备份:youdaonote-pull完整使用指南
  • Pspice for TI 库管理进阶:如何一劳永逸地添加外部模型(.lib/.olb)
  • ARM7TDMI复位电路设计与时序控制要点
  • GRBL-Plotter:从创意到现实,你的终极G代码控制解决方案
  • 火爆分享给团队,如何用TaoToken统一管理多模型API密钥与用量
  • 从科研绘图到专题地图:用Matlab m_map玩转六种实用投影与高级美化技巧
  • 从搜索引擎到推荐系统:TF-IDF在Python里的实战场景全解析
  • 从ArrayDeque和LinkedList源码看Java栈与队列的选择:一个数组与链表的实战抉择
  • 浏览器端VSCode集成实践:Monaco Editor深度配置与性能优化指南
  • 从npm到pnpm:我为什么换了包管理器?一份真实项目的迁移体验报告
  • 软件研发 --- 虚拟机文件格式大全与比对
  • 练了半年行书还是“太平正”?王铎57岁这招,3天打破僵局
  • 别再买错蓝牙模块了!手把手教你用HC05主机配对BT06从机(附完整AT指令清单)
  • 观察Taotoken用量看板如何帮助个人开发者优化月度AI支出
  • SketchUp STL插件终极指南:如何在SketchUp中完美处理3D打印文件
  • 风电并网谐波抑制:采样电路优化与PI+重复控制复合策略
  • Sora 2数字人动作自然度突破阈值:基于MotionCapture-Lab数据集的6维骨骼驱动校准方案
  • 在国产中标麒麟V7.0上搞定VMware Workstation 15.5.7的保姆级教程(附完整安装日志)
  • 别再只盯着准确率了!用Python手把手教你计算语义分割的MIoU(附完整代码与避坑指南)
  • 有关字典的函数
  • 英飞凌TC397开发板开箱实测:KIT_A2G_TC397_5V_TFT与3.3V版本到底怎么选?