【高心星出品】
装饰器的使用
状态管理
组件状态管理
@state组件内状态管理
@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。
javascript
@Entry
@Component
struct MyComponent {
//状态变量
@State count: number = 0;
build() {
Button(`点击次数: ${this.count}`)
.onClick(() => {
//更新状态变量
this.count += 1;
})
}
}
状态变量在声明的时候必须要进行初始化。
对象类型的状态变量
创建info类
javascript
/**
*作者:gxx
*日期:2024-03-15 11:41:10
*介绍:
*类型info
**/
export class info{
private name:string
private description:string
constructor(name:string,description:string) {
this.name=name
this.description=description
}
getname(){return this.name}
getdes(){return this.description}
}
使用info对象
javascript
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
//创建对象
@State pinfo:info=new info('gxx','a good teacher')
build() {
Row() {
Column() {
Row(){
Text(this.pinfo.getname())
.fontSize(20)
.fontWeight(FontWeight.Bolder)
Text(this.pinfo.getdes())
.fontSize(16)
.fontColor(Color.Gray)
}.width('100%')
.margin(3)
.padding(5)
.justifyContent(FlexAlign.SpaceAround)
.alignItems(VerticalAlign.Center)
Button('改变')
.width('60%')
.margin(10)
.onClick(()=>{
//改变对象 会动态刷新ui
this.pinfo=new info('ggl','a good man')
})
}
.width('100%')
}
.height('100%')
}
}
数组类型的状态变量
javascript
@Entry
@Component
struct Arraypage {
@State message: string = 'Hello World'
// 数组状态变量
@State arr: Array<string> = ['gxx', 'ggl', 'gxz', 'xyz']
build() {
Row() {
Column() {
ForEach(this.arr, (item, index) => {
Text((index + 1) + '. ' + item)
.fontSize(22)
.width('100%')
.margin({ top: 5, bottom: 5 })
.padding(5)
}, item => JSON.stringify(item))
Button('增加')
.width('60%')
.onClick(() => {
// 数组添加元素
this.arr.push('abc')
})
Button('减少')
.width('60%')
.onClick(() => {
// 数组移除元素
this.arr.pop()
})
.margin(10)
}
.width('100%')
}
.height('100%')
}
}
@prop父子组件单向同步
@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
父组件变化,子组件跟着变。
子组件变化,父组件不受影响。
javascript
@Component
struct child{
// 状态变量不能初始化,需要父组件传值
@Prop count:number
build(){
Column() {
Text('子组件内容:' + this.count)
.width('100%')
.fontSize(22)
.fontColor(Color.Red)
Button('子组件按钮')
.margin(5)
.width('60%')
.onClick(()=>{
this.count+=1
})
}
.width('100%')
.padding(5)
.margin({top:5,bottom:5})
.border({width:2,color:Color.Green,radius:5})
}
}
@Entry
@Component
struct Propdemo {
@State pcount:number=1
build() {
Row() {
Column() {
// 子组件的状态变量由父组件初始化
child({count:this.pcount})
Text('父组件内容:' + this.pcount)
.width('100%')
.fontSize(22)
Button('父组件按钮')
.margin(5)
.width('60%')
.onClick(()=>{
this.pcount+=1
})
}
.width('100%')
}
.height('100%')
}
}
@link父子组件双向同步
子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。
javascript
@Component
struct child{
// 状态变量不能初始化,需要父组件传值
@Link count:number
build(){
Column() {
Text('子组件内容:' + this.count)
.width('100%')
.fontSize(22)
.fontColor(Color.Red)
Button('子组件按钮')
.margin(5)
.width('60%')
.onClick(()=>{
this.count+=1
})
}
.width('100%')
.padding(5)
.margin({top:5,bottom:5})
.border({width:2,color:Color.Green,radius:5})
}
}
@Entry
@Component
struct Propdemo {
@State pcount:number=1
build() {
Row() {
Column() {
// 子组件的状态变量由父组件初始化
child({count:$pcount})
Text('父组件内容:' + this.pcount)
.width('100%')
.fontSize(22)
Button('父组件按钮')
.margin(5)
.width('60%')
.onClick(()=>{
this.pcount+=1
})
}
.width('100%')
}
.height('100%')
}
}
@watch状态变量观察者
@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数,常与@state、@prop、@link配合使用。
javascript
@Entry
@Component
struct Watchdemo {
@State message: string = 'Hello World'
// 观察者声明
@State @Watch('watchfun') num:number=1
@State col:Color=Color.Red
// 观察者对应的监听函数 name就是观察变量的名字
watchfun(name:string)
{
console.info('gxx num改变了')
if(this.num>10){
this.col=Color.Orange
}
}
build() {
Row() {
Column() {
Text(`当前次数:${this.num}`)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.padding(10)
.border({width:1,color:Color.Green,radius:5})
.backgroundColor(this.col)
.onClick(()=>{
this.num+=1
})
}
.width('100%')
}
.height('100%')
}
}
应用状态管理
LocalStorage页面级共享数据
LocalStorage是页面级的UI状态存储,通过@Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility实例内,在页面间共享状态。
页面内部共享数据
LocalStorage可以实现页面内部各个组件的数据共享。
javascript
// 声明一个localstorage
let stt=new LocalStorage({aa:44})
@Component
struct child{
// 单向同步绑定了num num改变不会影响stt
@LocalStorageProp('aa') num:number=1
build(){
Text('child: '+this.num)
.width('100%')
.padding(5)
.fontSize(25)
.onClick(()=>{
this.num+=1
})
.border({width:2,color:Color.Blue,radius:5})
}
}
@Entry (stt)
@Component
struct Index {
@State message: string = 'Hello World'
// 双向绑定count count改变stt一样会改变
@LocalStorageLink('aa') count: number = 1
build() {
Row() {
Column() {
child()
Text('index: ' + this.count)
.width('100%')
.fontSize(25)
.padding(5)
.onClick(()=>{
this.count+=1
})
.margin({top:20})
.border({width:2,color:Color.Red,radius:5})
}
.width('100%')
}
.height('100%')
}
}
页面间共享数据
LocalStorage还可以应用在多个页面之间,用于页面间数据共享。
EntryAbility文件中加载localstorage
javascript
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
// 声明一个storage
let storage=new LocalStorage({'jj':10})
// 加载页面的时候指定storage
windowStage.loadContent('pages/apage',storage, (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
apage中获取共享数据
javascript
import router from '@ohos.router'
// 取出该storage
let storage=LocalStorage.GetShared()
@Entry(storage)
@Component
struct Apage {
@State message: string = 'Hello World'
// 初始化给anum
@LocalStorageLink('jj') anum:number=1
build() {
Row() {
Column() {
Text('全局数据:'+this.anum)
.fontSize(25)
.fontWeight(FontWeight.Bold)
.border({width:2,color:Color.Red,radius:5})
.onClick(()=>{
this.anum+=1
})
Button('跳转')
.onClick(()=>{
router.pushUrl({
url: "pages/bpage"
})
})
.width('60%')
.margin({top:10})
}
.width('100%')
}
.height('100%')
}
}
bpage中获取共享数据
javascript
// 取出该storage
let storage=LocalStorage.GetShared()
@Entry(storage)
@Component
struct Bpage {
@State message: string = 'Hello World'
// 初始化给bnum
@LocalStorageLink('jj') bnum:number=1
build() {
Row() {
Column() {
Text('全局数据:'+this.bnum)
.fontSize(25)
.fontWeight(FontWeight.Bold)
.border({width:2,color:Color.Red,radius:5})
.onClick(()=>{
this.bnum+=1
})
}
.width('100%')
}
.height('100%')
}
}
AppStorage应用全局数据
AppStorage是在应用启动的时候会被创建的单例。它的目的是为了提供应用状态数据的中心存储,这些状态数据在应用级别都是可访问的。AppStorage将在应用运行过程保留其属性。属性通过唯一的键字符串值访问。
相对于localstorage,appstroage应用更灵活范围更大,可以在自定义组件,自定义对话框中使用。
javascript
// 设置一个全局存储器
AppStorage.SetOrCreate('pp',20)
// 直接拿来使用
@StorageLink('pp') apnum:number=1
PersistentStorage持久化全局数据
PersistentStorage将选定的AppStorage属性保留在设备磁盘上。应用程序通过API,以决定哪些AppStorage属性应借助PersistentStorage持久化。UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性访问都是对AppStorage的访问,AppStorage中的更改会自动同步到PersistentStorage。
注意:目前无法在虚拟机中演示效果
java
//初始化持久数据
PersistentStorage.PersistProp('aProp', 47);
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
@StorageLink('aProp') aProp: number = 48
build() {
Row() {
Column() {
Text(this.message)
// 应用退出时会保存当前结果。重新启动后,会显示上一次的保存结果
Text(`${this.aProp}`)
.onClick(() => {
this.aProp += 1;
})
}
}
}
}
具体执行流程如下:
-
触发点击事件后:
- 状态变量@StorageLink('aProp') aProp改变,触发Text组件重新刷新。
- @StorageLink装饰的变量是和AppStorage中建立双向同步的,所以@StorageLink('aProp') aProp的变化会被同步回AppStorage中。
- AppStorage中"aProp"属性的改变会同步到所有绑定该"aProp"的单向或者双向变量,在本示例中没有其他的绑定"aProp"的变量。
- 因为"aProp"对应的属性已经被持久化,所以在AppStorage中"aProp"的改变会触发PersistentStorage将新的改变写入本地磁盘。
-
后续启动应用:
-
执行PersistentStorage.PersistProp('aProp', 47),在首先查询在PersistentStorage本地文件查询"aProp"属性,成功查询到。
-
将在PersistentStorage查询到的值写入AppStorage中。
-
在Index组件里,@StorageLink绑定的"aProp"为PersistentStorage写入AppStorage中的值,即为上一次退出应用存入的值。
-
Environment设备环境信息
Environment是ArkUI框架在应用程序启动时创建的单例对象。它为AppStorage提供了一系列描述应用程序运行状态的属性。
Environment设备参数
键 | 数据类型 | 描述 |
---|---|---|
accessibilityEnabled | boolean | 获取无障碍屏幕读取是否启用。 |
colorMode | ColorMode | 色彩模型类型:选项为ColorMode.LIGHT: 浅色,ColorMode.DARK: 深色。 |
fontScale | number | 字体大小比例,范围: [0.85, 1.45]。 |
fontWeightScale | number | 字体粗细程度,范围: [0.6, 1.6]。 |
layoutDirection | LayoutDirection | 布局方向类型:包括LayoutDirection.LTR: 从左到右,LayoutDirection.RTL: 从右到左。 |
languageCode | string | 当前系统语言值,取值必须为小写字母, 例如zh。 |
注意:对于environment只能查询信息,不能修改信息。
javascript
// 将languagecode写入appstorage
Environment.EnvProp('languageCode','cn')
// 直接获取该值
@StorageProp('languageCode') mode:string='cn'