【HarmonyOS】鸿蒙开发之状态管理——第2.2章

状态管理简介

ArkUI 开发提供了多维度的状态管理机制。状态管理机制能使父子组件之间,爷孙组件之间数值传递,还可以跨设备传递。从数据的传递形式看,可以分为只读的单向传递和可变更的双向传递。与vue的用法特别像。

@State修饰符

@State有以下特征:

  1. 支持多种数据类型: class number boolean string 强类型的值和引用类型。允许强类型构成的数组:Array< class >、Array< string >、Array< boolean >、Array< number >。不允许object和any
  2. 内部私有: 标记为@State的属性,表明当前变量为私有变量,只能当前组件内访问。
  3. 支持多个实例: 组件不同实例的内部状态数据独立
  4. 本地初始化: 必须为所有 @State 变量分配初始值

案例:

bash 复制代码
@Entry
@Component
export struct stateData{
  @State title:string = "迪加奥特曼"
  build(){
    Column(){
      Text(this.title).fontSize(36)
      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.title = "迪迦奥特曼他爹"
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Prop修饰符

@Prop与@State有相同语义,但是初始方式不同,用法也不同。@Prop用在父组件内。父组件能改变子组件使用@Prop装饰的数据。反观,子组件的更改不影响父组件。
@Prop有以下特征:

  1. 内部私有: 标记为@Prop的属性,表明当前变量为私有变量,只能当前组件内访问。
  2. 支持简单数据类型: 支持number,string,boolean类型。
  3. 支持多个实例: 组件不同实例的内部状态数据独立。
  4. 不支持内部初始化: 在创建组件的新实例时,必须将值传递给 @Prop 修饰的变量进行初始化,不支持在组件内部进行初始化。

案例:

bash 复制代码
@Entry
@Component
export struct propData{
  @State title:string = "迪加奥特曼"
  build(){
    Column(){
      childCpn({ childData:this.title })// 必须初始化子组件的childData字段

      Divider().margin({top:10,bottom:10})

      Text("父组件:"+this.title).fontSize(36)

      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.title = "迪迦奥特曼他爹"// 父组件的更改影响子组件
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Component
struct childCpn{
  @Prop childData:string; // 不允许本地初始化
  build(){
    Text(this.childData).fontSize(36).onClick(()=>{
      this.childData = "泰罗奥特曼" // 子组件的更改不影响父组件
    })

  }
}

@Link修饰符

@Link与@State有相同语义。@Link装饰的变量能和父组件的@State装饰的变量建立双休的数据绑定。
@Link有以下特征:

  1. 内部私有: 标记为@Link的属性,表明当前变量为私有变量,只能当前组件内访问。
  2. 支持多种数据类型: 支持class,number,string,boolean或者这些类型的数据。
  3. 支持多个实例: 组件不同实例的内部状态数据独立。
  4. 不支持内部初始化: 在创建组件的新实例时,必须将值传递给 @Link 修饰的变量进行初始化,不支持在组件内部进行初始化。初始化使用 $ 符号,例如:$data。

案例:

bash 复制代码
@Entry
@Component
export struct propData{
  @State title:string = "迪加奥特曼"
  build(){
    Column(){
      childCpn({ childData:$title })// 必须初始化子组件的childData字段

      Divider().margin({top:10,bottom:10})

      Text("父组件:"+this.title).fontSize(36)

      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.title = "迪迦奥特曼他爹"// 父组件的更改影响子组件
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Component
struct childCpn{
  @Link childData:string; // 不允许本地初始化
  build(){
    Text(this.childData).fontSize(36).onClick(()=>{
      this.childData = "泰罗奥特曼" // 子组件的更改不影响父组件
    })

  }
}

@StorageLink修饰符

@Link与@State有相同语义。@Link装饰的变量能和父组件的@State装饰的变量建立双休的数据绑定。
@Link有以下特征:

  1. 本地初始化: @StorageLink装饰的变量分配初始值。
  2. 支持多种数据类型: 支持与@State一样的数据类型,同时支持object。
  3. 数据状态全局化: @StorageLink装饰的数据变化后全局都会改变
  4. 数据持久化: 通过搭配 PersistentStorage 接口实现数据持久化

绑定数据

bash 复制代码
@Entry
@Component
export struct storageLink{
  @StorageLink('date1') data:string = "第一个案例:绑定数据"
  build(){
    Column(){
      Text("随机数:"+this.data).fontSize(36)
      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.data = Math.random()+""
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

双向绑定数据

bash 复制代码
@Entry
@Component
export struct storageLink{
  @StorageLink('date2') data:string = "第二个案例:双向绑定数据"
  build(){
    Column(){
      Text("随机数:"+this.data).fontSize(36).fontColor(Color.Red).margin({bottom:10})
      CustomCpn()
      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.data = Math.random()+""
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Component
struct CustomCpn {
  @StorageLink('date2') time: string = "自定义组件";

  build() {
    Text(`子组件【${this.time}】`)
      .fontColor(Color.Blue)
      .fontSize(20)
      .onClick(() => {
        this.time = Math.random()+""
      })
  }
}

页面间数据绑定

页面一

bash 复制代码
import router from '@ohos.router';
@Entry
@Component
export struct storageLink{
  @StorageLink('date3') data:string = "第三个案例:页面间数据绑定";//tips的值以'key'第一次出现的为准
  build(){
    Column(){
      Text("随机数:"+this.data).fontSize(36).margin({bottom:20})
      CustomCpn()
      Divider().margin({top:50,bottom:50})
      Button("修改数据").onClick(()=>{
        this.data = Math.random()+""
      })
      Button('跨页面数据绑定')
        .onClick(() => {
          router.pushUrl({url: "pages/home/arkTsIntro/stateManage/storageLink/demo3/Two"})// 打开第二个页面
        })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Component
struct CustomCpn {
  @StorageLink('date3') time: string = "自定义组件";
  build() {
    Text(`子组件【${this.time}】`)
      .fontColor(Color.Blue)
      .fontSize(20)
      .onClick(() => {
        this.time = Math.random()+""
      })
  }
}

页面二

bash 复制代码
@Entry
@Component
export struct storageLink2{
  @StorageLink('date3') data:string = "案例三,第二个页面";//tips的值以'key'第一次出现的为准
  build(){
    Column(){
      Text("随机数:"+this.data).fontSize(36)
      Divider().margin({top:50,bottom:50})
      Button("修改数据").onClick(()=>{
        this.data = Math.random()+""
      }).margin({bottom:20})
      Button("返回上一页").onClick(()=>{
        router.back()
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

持久化数据

bash 复制代码
// 持久化存储key并设置默认值
PersistentStorage.PersistProp("date4", "持久化数据")
//持久化数据
@Entry
@Component
export struct storageLink{
  @StorageLink('date4') data:string = "第四个案例:持久化数据"
  build(){
    Column(){
      Text("随机数:"+this.data).fontSize(36)
      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
        this.data = Math.random()+""
      }).margin({bottom:20})
      Button('跨页面数据绑定')
        .onClick(() => {
          router.pushUrl({url: "pages/home/arkTsIntro/stateManage/storageLink/demo3/Two"})// 打开第二个页面
        })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

@Watch修饰符

@Watch用于监听被Watch装饰的变量值变化,当他数值发生更改,会触发相应的方法(funcName)。

bash 复制代码
@Entry
@Component
export struct watchData{
  @State @Watch("funcName") num:number = 0
  @State title:string = "@Watch装饰变量"

  funcName(){
    this.title = "我发生改变啦"+Math.random()*100;
  }
  build(){
    Column(){
      Text("标题:"+this.title).fontSize(26).margin({bottom:10})
      Text("数值:"+this.num).fontSize(26)

      Divider().margin({top:50,bottom:50})
      Button("修改标题").onClick(()=>{
       this.num++;
      })
    }.alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .height("100%")
  }
}

注意:@Watch装饰器只能监听 @State 、 @Prop 、 @Link 、 @ObjectLink 、 @Provide 、 @Consume 、 @StorageProp 以及 @StorageLink 装饰的变量

✨ 踩坑不易,还希望各位大佬支持一下 \textcolor{gray}{踩坑不易,还希望各位大佬支持一下} 踩坑不易,还希望各位大佬支持一下

📃 个人主页: \textcolor{green}{个人主页:} 个人主页: 沉默小管

📃 个人网站: \textcolor{green}{个人网站:} 个人网站: 沉默小管

📃 个人导航网站: \textcolor{green}{个人导航网站:} 个人导航网站: 沉默小管导航网

📃 我的开源项目: \textcolor{green}{我的开源项目:} 我的开源项目: vueCms.cn

🔥 技术交流 Q Q 群: 837051545 \textcolor{green}{技术交流QQ群:837051545} 技术交流QQ群:837051545

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

如果有不懂可以留言,我看到了应该会回复

如有错误,请多多指教

相关推荐
枫叶丹45 小时前
【HarmonyOS之旅】HarmonyOS开发基础知识(三)
华为od·华为·华为云·harmonyos
SoraLuna10 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
AORO_BEIDOU13 小时前
单北斗+鸿蒙系统+国产芯片,遨游防爆手机自主可控“三保险”
华为·智能手机·harmonyos
博览鸿蒙15 小时前
鸿蒙操作系统(HarmonyOS)的应用开发入门
华为·harmonyos
Damon小智1 天前
HarmonyOS NEXT 技术实践-基于基础视觉服务的多目标识别
华为·harmonyos
匹马夕阳1 天前
华为笔记本之糟糕的体验
华为·笔记本电脑
egekm_sefg1 天前
华为、华三交换机纯Web下如何创关键VLANIF、操作STP参数
网络·华为
岳不谢2 天前
华为DHCP高级配置学习笔记
网络·笔记·网络协议·学习·华为
爱笑的眼睛112 天前
uniapp 极速上手鸿蒙开发
华为·uni-app·harmonyos
K.P2 天前
鸿蒙元服务从0到上架【第三篇】(第二招有捷径)
华为·harmonyos·鸿蒙系统