鸿蒙Harmony(八)ArkUI--状态管理器之@State

状态管理

在声明式UI中,是以状态驱动视图更新

状态:指驱动视图更新的数据(被装饰器标记的变量)

  • @State
  • @Prop 和 @Link
  • @Provide和 @Consume

@State

  • @State装饰器标记的变量必须初始化,不能为空值
  • @State支持Object 、class、string、number、boolean、enum 类型以及这些类型的数组
  • 嵌套类型以及数组中的对象属性无法触发视图更新
    无法触发视图更新的代码示例如下:

嵌套类型无法刷新视图

javascript 复制代码
// 嵌套类型
class Person{
   name:string
   age:number
   friend:Person

  constructor(name:string,age:number,friend?:Person) {
    this.name=name
    this.age=age
    this.friend=friend
  }
}

@Entry
@Component
struct Index {
  @State xiaoming: Person = new Person('xiaoming',13)
  @State xiaohong: Person = new Person('xiaohong',14,new Person("lilei",14))

  build() {
    Row() {
      Column() {
        Text(this.xiaoming.name+"的年龄"+this.xiaoming.age)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .onClick(()=>{
            // 会刷新ui
            this.xiaoming.age++
          })

        Text(this.xiaohong.name+"的朋友的年龄"+this.xiaohong.friend.age)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .onClick(()=>{
            // 嵌套类型,不会刷新ui
            this.xiaohong.friend.age++
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

数组中的对象属性无法触发视图更新

javascript 复制代码
class Person {
  name: string
  age: number
  friend: Person

  constructor(name: string, age: number, friend?: Person) {
    this.name = name
    this.age = age
    this.friend = friend
  }
}

@Entry
@Component
struct Index {
  @State xiaoming: Person = new Person('xiaoming', 13)
  @State friendList: Person[] = [
    new Person("lilei", 14),
    new Person("lilei2", 15)
  ]

  build() {
    Row() {
      Column() {
        Text("朋友列表")
          .fontSize(40)
          .fontWeight(FontWeight.Bold)
        Button("添加朋友")
          .onClick(() => {
            // 点击会增加
            let friendIndex = this.friendList.length
            this.friendList.push(new Person("lilei" + friendIndex, 20))
          })
        ForEach(this.friendList, (item, index) => {
          Row({space:10}) {
            Text(item.name + "的年龄" + item.age)
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
              .onClick(() => {
                // 点击不会发生年龄变更
                item.age++
              })
            Button("删除朋友")
              .onClick(() => {
                // 点击会删除当前项
                this.friendList.splice(index, 1)
              })
          }.width('100%').justifyContent(FlexAlign.SpaceAround)
          .margin({bottom:10,left:10,right:10})
          .borderRadius(15)
          .padding(10)
          .backgroundColor('#cccccc')

        })

      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Start)
    }
    .height('100%')
  }
}

应用示例

涉及内容:

基础组件:Progress CheckBox

容器组件:Stack List

javascript 复制代码
class Task {
  static id: number = 1
  name: string = '任务' + Task.id++
  isDone: boolean = false
}

@Extend(Text) function finishedTask() {
  .decoration({ type: TextDecorationType.LineThrough })
  .fontColor('#B1B2B1')
}

@Entry
@Component
struct TaskPage {
  // 总任务数量
  @State totalTask: number = 0
  @State finishTask: number = 0
  @State taskList: Array<Task> = []

  build() {
    Column() {
      // 1.顶部任务统计部分
      this.TaskProgressView()
      // 2.新增任务
      Button("新增任务").onClick(() => {
        this.taskList.push(new Task())
        this.totalTask = this.taskList.length
      }).width("60%")
        .margin({ top: 10 })
      // 3.任务列表
      List() {
        ForEach(this.taskList, (item, index) => {
          ListItem() {
            this.TaskItemView(item)
          }.swipeAction({ end: this.getDeleteButton(index) })// 向左滑动,出现删除按钮
        })
      }.layoutWeight(1) // 高度权重
      .width('100%')
      .alignListItem(ListItemAlign.Center)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#eeeeee')
    .justifyContent(FlexAlign.Start)
  }

  @Builder TaskProgressView() {
    Row() {
      Text("任务进度:")
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ right: 40 })
      Stack() {
        Progress({ value: this.finishTask, type: ProgressType.Ring, total: this.totalTask }).width(120)
        Text(this.finishTask + "/" + this.totalTask)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
      }
    }.commonCardStyle()
    .height(200)
    .padding({ left: 20, right: 20 })
    .justifyContent(FlexAlign.Center)
  }

  @Builder TaskItemView(task: Task) {
    Row() {
      // 这里不生效,原因:state 数组对象嵌套不刷新视图
      if (task.isDone) {
        Text(task.name)
          .fontSize(15)
          .fontWeight(FontWeight.Bold)
          .margin({ right: 40 })
          .finishedTask()
      } else {
        Text(task.name)
          .fontSize(15)
          .fontWeight(FontWeight.Bold)
          .margin({ right: 40 })
      }
      Checkbox()
        .select(task.isDone).onChange((isChecked) => {
        task.isDone = isChecked
        this.finishTask = this.taskList.filter(item => item.isDone).length
      })
    }.commonCardStyle()
    .height(100)
    .padding({ left: 20, right: 20 })
    .justifyContent(FlexAlign.SpaceBetween)
  }

  @Builder getDeleteButton(index: number) {
    Button({ type: ButtonType.Circle }) {
      Image($r('app.media.del'))
    }
    .onClick(() => {
      this.taskList.splice(index, 1)
      this.finishTask = this.taskList.filter(item => item.isDone).length
      this.totalTask = this.taskList.length
    })
    .width(50)
    .height(50)
    .padding(10)
    .margin({ right: 5 })
    .backgroundColor('#ffffff')
  }

  @Styles commonCardStyle(){
    .width('95%')
    .margin({ left: 10, right: 10, top: 10 })
    .borderRadius(20)
    .backgroundColor('#ffffff')
    .shadow({ radius: 6, color: '#1f000000', offsetX: 2, offsetY: 4 })
  }
}

@Provide和 @Consume

相关推荐
威哥爱编程7 小时前
【鸿蒙开发案例篇】拒绝裸奔!鸿蒙6实现PDF动态加密
harmonyos·arkts·arkui
是Yu欸8 小时前
①【openFuyao】智算时代的异构算力连接器
华为·华为云·算力·openfuyao
yilan_n10 小时前
在Linux下使用Termony搭建HNP自验证环境全指南
linux·harmonyos·termony·hnp·命令行适配
志尊宝12 小时前
HarmonyOS ArkTS 入门(一)
华为·harmonyos
90后的晨仔12 小时前
🧩 一文搞懂 HarmonyOS 中的 HAP、HAR 和 HSP:它们到底是什么?怎么用?
harmonyos
m0_6855350813 小时前
光是如何产生的?
华为·光学·光学设计·光学工程·镜头设计
Simon席玉13 小时前
C++的命名重整
开发语言·c++·华为·harmonyos·arkts
我是Feri14 小时前
HarmonyOS 6.0 视频播放组件使用教程
华为·音视频·harmonyos
大土豆的bug记录16 小时前
鸿蒙权限授权弹窗(推荐)
华为·harmonyos
马剑威(威哥爱编程)16 小时前
【鸿蒙开发案例篇】基于MindSpore Lite的端侧人物图像分割案例
华为·harmonyos