注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下
如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识
专栏地址: https://blog.csdn.net/qq_56760790/category_12794123.html
目录
[1. 应用状态基本介绍](#1. 应用状态基本介绍)
[2. LocalStorage:页面级UI状态存储](#2. LocalStorage:页面级UI状态存储)
[2.1 基本介绍](#2.1 基本介绍)
[2.2 用法](#2.2 用法)
[2.3 两个页面共享一个对象](#2.3 两个页面共享一个对象)
[2.4 页面间共享](#2.4 页面间共享)
[2.5 应用逻辑中使用](#2.5 应用逻辑中使用)
[3. AppStorage:应用全局的UI状态存储](#3. AppStorage:应用全局的UI状态存储)
[3.1 基本介绍](#3.1 基本介绍)
[3.2 基本用法](#3.2 基本用法)
[3.3 经常使用的方法](#3.3 经常使用的方法)
[3.4 代码示例](#3.4 代码示例)
[4. PersistentStorage:持久化存储UI状态](#4. PersistentStorage:持久化存储UI状态)
[4.1 基本介绍](#4.1 基本介绍)
[4.2 限制条件](#4.2 限制条件)
[4.3 使用场景](#4.3 使用场景)
[5. 学习地址](#5. 学习地址)
1. 应用状态基本介绍
- LocalStorage:页面级UI状态存储,通常用于UIAbility内、页面间的状态共享。(内存- 注意:和前端的区分开,它非持久化,非全应用)
- AppStorage:特殊的单例LocalStorage对象,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。(内存-非持久化-退出应用同样消失)
- PersistentStorage:持久化存储UI状态,通常和AppStorage配合使用,选择AppStorage存储的数据写入磁盘,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。(写入磁盘-持久化状态-退出应用 数据同样存在)
- Environment:应用程序运行的设备的环境参数,环境参数会同步到AppStorage中,可以和AppStorage搭配使用。
官方文档地址:
2. LocalStorage:页面级UI状态存储
2.1 基本介绍
LocalStorage
是页面级的UI状态存储,通过 @Entry
装饰器接收的参数可以在页面内共享同一个 LocalStorage
实例。 LocalStorage
也可以在 UIAbility
内,页面间共享状态。
2.2 用法
用法
- 创建
LocalStorage
实例:const storage = new LocalStorage({ key: value })
- 单向
@LocalStorageProp('user')
组件内可变 - 双向
@LocalStorageLink('user')
全局均可变
2.3 两个页面共享一个对象
-
创建一个共享的状态
export class PersonModel {
username: string = '张三'
age: number = 18
}let pp = new PersonModel()
pp.username = "东林"
pp.age = 29
// 创建新实例并使用给定对象初始化
let para: Record<string, PersonModel> = { 'user': pp };
let local: LocalStorage = new LocalStorage(para);export { local }
-
页面1
import { local, PersonModel } from '../models/PersonModel'
import { router } from '@kit.ArkUI'@Entry(local)
@Component
struct LocalStorageCaseA {
@LocalStorageLink("user")
user: PersonModel = new PersonModelbuild() { Column() { Text(this.user.username) .fontSize(40) .onClick(() => { this.user.username = "王八蛋" router.pushUrl({url:'pages/LocalStorageCaseB'}) }) } .height('100%') .width('100%') } }
-
页面2
import { local, PersonModel } from '../models/PersonModel'
import { router } from '@kit.ArkUI'@Entry(local)
@Component
struct LocalStorageCaseB {
@LocalStorageLink("user")
user: PersonModel = new PersonModel()
build() {
Column() {
Text(this.user.username)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.user.username = "李四"
router.back()
})Text(this.user.age.toString()) .fontSize(50) .fontWeight(FontWeight.Bold) } .height('100%') .width('100%') } }
2.4 页面间共享
如果你想在UIAbility
中共享某个localStorage,可以在入口处直接初始化传入
-
可以在loadContent过程中直接传入创建的LocalStorage
-
const storage = LocalStorage.GetShared()
得到实例 -
通过
@Entry(storage)
传入页面 -
在UIAbility进行初始化storage
class UserInfoClass {
name?: string = ""
age?: number = 0
}
let user: Record<string, UserInfoClass> = { "user": {
name: '水若寒宇',
age: 34
}};
const sharedStorage = new LocalStorage(user)onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testUIAbility', '%{public}s', 'Ability onWindowStageCreate');windowStage.loadContent('pages/Index',local, (err) => { if (err.code) { hilog.error(0x0000, 'testUIAbility', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testUIAbility', 'Succeeded in loading the content.'); });
}
-
在页面中传入
const shareLocal = LocalStorage.GetShared()
@Entry(shareLocal)
2.5 应用逻辑中使用
@Entry
@Component
struct Index {
build() {
Button('应用逻辑中使用')
.onClick(()=>{
let para: Record<string,number> = { 'PropA': 47 };
let storage: LocalStorage = new LocalStorage(para); // 创建新实例并使用给定对象初始化
let propA: number | undefined = storage.get('PropA') // propA == 47
console.log(propA?.toString())
let link1: SubscribedAbstractProperty<number> = storage.link('PropA'); // link1.get() == 47
let link2: SubscribedAbstractProperty<number> = storage.link('PropA'); // link2.get() == 47
let prop: SubscribedAbstractProperty<number> = 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
})
}
}
3. AppStorage:应用全局的UI状态存储
LocalStorage是针对UIAbility的状态共享- 一个UIAbility有个页面
一个应用可能有若干个UIAbility
3.1 基本介绍
概述
AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。
AppStorage可以和UI组件同步,且可以在应用业务逻辑中被访问。
AppStorage支持应用的主线程内多个UIAbility实例间的状态共享。
AppStorage中的属性可以被双向同步,数据可以是存在于本地或远程设备上,并具有不同的功能,比如数据持久化(详见PersistentStorage)。这些数据是通过业务逻辑中实现,与UI解耦,如果希望这些数据在UI中使用,需要用到@StorageProp和@StorageLink。
3.2 基本用法
AppStorage
是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。-注意它也是内存数据,不会写入磁盘
第一种用法-使用UI修饰符
- 如果是初始化使用 AppStorage.setOrCreate(key,value)
- 单向 **@StorageProp('user')**组件内可变
- 双向 **@StorageLink('user')**全局均可变
第二种用法 使用API方法
- **AppStorage.get<ValueType>(key)**获取数据
- **AppStorage.set<ValueType>(key,value)**覆盖数据
- **const link: SubscribedAbstractProperty<ValueType> = AppStorage.Link(key)**覆盖数据
-
- **link.set(value)**修改
- **link.get()**获取
3.3 经常使用的方法
// 存数据
AppStorage.setOrCreate("token", "123456")
AppStorage.setOrCreate<string>("username", "东林")
// 获取数据
const token: string | undefined = AppStorage.get("token")
const username = AppStorage.get<string>("username")
// 删除数据
AppStorage.delete("token")
3.4 代码示例
import { promptAction, router } from '@kit.ArkUI'
@Entry
@Component
struct AppStorageCase {
@State
username: string = "admin"
@State
password: string = "123456"
login() {
if (this.username === 'admin' && this.password === "123456") {
// 要将当前用户的身份存入AppStorage
AppStorage.setOrCreate<UserInfoModel>("userInfo", new UserInfoModel('东林', 20))
router.pushUrl({ url: 'pages/Detail' })
} else {
promptAction.showToast({ message: '登录失败' })
}
}
build() {
Row() {
Column({ space: 20 }) {
TextInput({ placeholder: '请输入用户名', text: $$this.username })
TextInput({ placeholder: '请输入密码', text: $$this.password })
.type(InputType.Password)
Button("登录")
.width('100%')
.onClick(() => {
this.login()
})
}
.padding(20)
.width('100%')
}
.height('100%')
}
}
export class UserInfoModel {
username: string = ''
age: number = 0
constructor(username: string, age: number) {
this.username = username
this.age = age
}
}
import { UserInfoModel } from './Index'
@Entry
@Component
struct Detail {
@State userInfo: UserInfoModel | null | undefined = null
aboutToAppear(): void {
const userInfo = AppStorage.get<UserInfoModel>("userInfo")
this.userInfo = userInfo
}
build() {
Column() {
Text(this.userInfo?.username)
Text(this.userInfo?.age.toString())
}
.height('100%')
.width('100%')
}
}
4. PersistentStorage:持久化存储UI状态
前两个小节介绍的LocalStorage和AppStorage都是运行时的内存,但是在应用退出再次启动后,依然能保存选定的结果,是应用开发中十分常见的现象,这就需要用到PersistentStorage。
PersistentStorage是应用程序中的可选单例对象。此对象的作用是持久化存储选定的AppStorage属性,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。
4.1 基本介绍
概述
PersistentStorage将选定的AppStorage属性保留在设备磁盘上。应用程序通过API,以决定哪些AppStorage属性应借助PersistentStorage持久化。UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性访问都是对AppStorage的访问,AppStorage中的更改会自动同步到PersistentStorage。
PersistentStorage和AppStorage中的属性建立双向同步。应用开发通常通过AppStorage访问PersistentStorage,另外还有一些接口可以用于管理持久化属性,但是业务逻辑始终是通过AppStorage获取和设置属性的。
4.2 限制条件
PersistentStorage允许的类型和值有:
- number, string, boolean, enum 等简单类型。
- 可以被JSON.stringify()和JSON.parse()重构的对象。例如Date, Map, Set等内置类型则不支持,以及对象的属性方法不支持持久化。
PersistentStorage不允许的类型和值有:
- 不支持嵌套对象(对象数组,对象的属性是对象等)。因为目前框架无法检测AppStorage中嵌套对象(包括数组)值的变化,所以无法写回到PersistentStorage中。
- 不支持undefined 和 null 。
4.3 使用场景
从AppStorage中访问PersistentStorage初始化的属性
@Entry
@Component
struct Index {
build() {
Column() {
Button('点我')
.onClick(() => {
PersistentStorage.persistProp<string>('test', '123456');
const test = AppStorage.get<string>('test'); // returns 47
console.log(test)
})
}.width('100%')
.height('100%')
}
}
官方参考文档: