HarmonyOS | 状态管理(六) | LocalStorage(页面级UI状态存储)

系列文章目录

1.HarmonyOS | 状态管理(一) | @State装饰器
2.HarmonyOS | 状态管理(二) | @Prop装饰器
3.HarmonyOS | 状态管理(三) | @Link装饰器
4.HarmonyOS | 状态管理(四) | @Provide和@Consume装饰器
5.HarmonyOS | 状态管理(五) | @Observed装饰器和@ObjectLink装饰器


文章目录

  • 系列文章目录
  • 前言
  • [一、LocalStorage 是 什么?](#一、LocalStorage 是 什么?)
  • 二、特性
  • [三、LocalStorage 使用场景](#三、LocalStorage 使用场景)
  • 四、两种不同的同步类型装饰器
    • [1. @LocalStorageProp 装饰器 (单向同步)](#1. @LocalStorageProp 装饰器 (单向同步))
    • [2. @LocalStorageLink 装饰器 (双向同步)](#2. @LocalStorageLink 装饰器 (双向同步))
    • [3. 将LocalStorage实例从UIAbility共享到一个或多个视图](#3. 将LocalStorage实例从UIAbility共享到一个或多个视图)
  • 总结

前言

以上文章介绍的 装饰器 仅能页面内,即一个组件树上 共享状态变量,后续文章讲解应用级的状态管理。

本篇文章我们讲解的是:LocalStorage (页面级UI状态存储)


一、LocalStorage 是 什么?

页面级UI状态存储,通常用于UIAbility内、页面间的状态共享

二、特性

  • 应用程序可以创建多个LocalStorage实例,LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。

  • 组件树的根节点,即被@Entry装饰的@Component,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。

  • 被@Component装饰的组件最多可访问一个LocalStorage实例,未被@Entry装饰的组件不可被独立分配LocalStorage实例,只能接受父组件通过@Entry传递来的LocalStorage实例。

  • 一个LocalStorage实例在组件树上可以被分配给多个组件。

  • LocalStorage中的所有属性都是可变的。

  • 应用程序决定LocalStorage对象的生命周期。当应用释放最后一个指向LocalStorage的引用时,比如销毁最后一个自定义组件,LocalStorage将被JS Engine垃圾回收。

三、LocalStorage 使用场景

typescript 复制代码
let storage = new LocalStorage({ 'PropA': 47 }); // 创建新实例并使用给定对象初始化
let propA = storage.get('PropA') // propA == 47
let link1 = storage.link('PropA'); // link1.get() == 47
let link2 = storage.link('PropA'); // link2.get() == 47
let prop = storage.prop('PropA'); // prop.get() = 47
link1.set(48); // two-way sync: link1.get() == link2.get() == prop.get() == 48
prop.set(1); // one-way sync: prop.get()=1; but link1.get() == link2.get() == 48
link1.set(49); // two-way sync: link1.get() == link2.get() == prop.get() == 49

四、两种不同的同步类型装饰器

LocalStorage 根据与 @Component 装饰的组件的同步类型不同,提供了两个装饰器:

@LocalStorageProp:@LocalStorageProp 装饰的变量与LocalStorage中给定属性建立单向同步关系。
@LocalStorageLink:@LocalStorageLink 装饰的变量与LocalStorage中给定属性建立双向同步关系。

1. @LocalStorageProp 装饰器 (单向同步)

typescript 复制代码
let storageProp = new LocalStorage({ 'PropA': 47 });

@Entry(storageProp)
@Component
struct LocalStoragePropPage {
  // @LocalStorageProp变量装饰器与LocalStorage中的'PropA'属性建立单向绑定
  @LocalStorageProp('PropA') storagePropOne: number = 1;

  build() {
     Column({ space: 15 }) {
         // 点击后从47开始加1,只改变当前组件显示的storagePropOne,不会同步到LocalStorage中
         Button(`Parent from LocalStorage ${this.storagePropOne}`).onClick(() => this.storagePropOne += 1)
         ChildProp()
     }

  }
}

@Component
struct ChildProp {
  // @LocalStorageProp变量装饰器与LocalStorage中的'PropA'属性建立单向绑定
  @LocalStorageProp('PropA') storagePropTwo: number = 2;

  build(){
    Column({ space: 15 }) {
      // 当LocalStoragePropPage改变时,当前storagePropTwo不会改变,显示47
      Text(`Parent from LocalStorage ${this.storagePropTwo}`)
    }
  }
}
  • LocalStoragePropPage 中对 this.storagePropOne 的修改,只会在 LocalStoragePropPage 中生效,并没有同步回 storageProp ;
  • Child 组件中,Text 绑定的 storagePropTwo 依旧显示47。
typescript 复制代码
let storage = new LocalStorage({ 'PropA': 50 });

@Component
struct Child{
    // @LocalStorageLink 与 LocalStorage中的'PropA'属性建立双向绑定
    @LocalStorageLink('PropA') storageLinkTwo : number = 1;

    build(){
       Button(`Child from LocalStorage ${this.storageLinkTwo}`)
         // 更改将同步至LocalStorage中的'PropA'以及Parent.storageLinkOne
         .onClick(()=> this.storageLinkTwo += 1)
    }
}

// 使LocalStorage可从@Component组件访问
@Entry(storage)
@Component
struct LocalStoragePager {
  // @LocalStorageLink 与 LocalStorage中的'PropA'属性建立双向绑定
  @LocalStorageLink('PropA') storageLinkOne : number = 1

  build() {
    Column({ space: 15 }) {
      Button(`Parent from LocalStorage ${this.storageLinkOne}`)
        .onClick(() => this.storageLinkOne += 1)
      // @Component子组件自动获得对LocalStoragePager LocalStorage实例的访问权限。
      Child()
    }
  }
}
  • 使用构造函数创建LocalStorage实例storage;
  • 使用@Entry装饰器将storage添加到LocalStoragePager顶层组件中;
  • @LocalStorageLink绑定LocalStorage对给定的属性,建立双向数据同步。

3. 将LocalStorage实例从UIAbility共享到一个或多个视图

上面的实例中,LocalStorage的实例仅在一个 @Entry装饰的组件和其所属的子组件一个页面 )中共享,如果希望其在多个视图 中共享,可以在所属 UIAbility 中创建 LocalStorage实例 ,并调用windowStage.loadContent

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';

let para:Record<string,number> = { 'PropB': 47 };
let localStorage: LocalStorage = new LocalStorage(para);

export default class EntryAbility extends UIAbility {

  storage: LocalStorage = localStorage
  
  onWindowStageCreate(windowStage: window.WindowStage) {
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/status/LocalStorageUIAbilityPage', this.storage);
  }
}
typescript 复制代码
// 通过GetShared接口获取stage共享的LocalStorage实例
let storages = LocalStorage.GetShared()

@Entry(storages)
@Component
struct LocalStorageUIAbilityPage {
  @LocalStorageLink('PropB') varA: number = 1;

  build() {
    Column() {
      Text(`${this.varA}`).fontSize(50)
    }
  }
}

注:

  • 在UI页面通过getShared接口获取在通过loadContent共享的LocalStorage实例。

  • LocalStorage.getShared只在模拟器或者实机上才有效,不能在Preview预览器中使用。


总结

1.LocalStorage实例可以在页面内共享,也可以通过GetShared接口,实现跨页面、UIAbility实例内共享。

2.@LocalStorageProp 装饰的变量与LocalStorage中给定属性建立单向同步关系。

3.@LocalStorageLink 装饰的变量与LocalStorage中给定属性建立双向同步关系。

4.通过windowStage.loadContent设置LocalStorage的属性,可以在多个页面共享该属性值。

相关推荐
一只栖枝6 小时前
华为 HCIE 大数据认证中 Linux 命令行的运用及价值
大数据·linux·运维·华为·华为认证·hcie·it
zhanshuo10 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo10 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw15 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw16 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw18 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw19 小时前
鸿蒙音频编码
harmonyos
whysqwhw19 小时前
鸿蒙音频解码
harmonyos
whysqwhw19 小时前
鸿蒙视频解码
harmonyos
whysqwhw19 小时前
鸿蒙视频编码
harmonyos