HarmonyOS 学习记录系列之装饰器写法

2025-07-05  本文已影响0人  简单就是真

装饰器用法

在HarmonyOS应用开发中,状态管理是构建动态用户界面的重要部分。ArkUI框架提供了多种装饰器来管理状态变量,包括 @State、@Prop、@Link、@Provide、@Consume、@ObjectLink、@StorageProp、 等。下面将详细介绍这些装饰器的用法

1.@State 装饰器

@State 是HarmonyOS中最基本的状态管理装饰器,用于在组件内部声明一个状态变量。
@State装饰器标记的变量必须初始化,不能为空值;@State支持Object、class、string、number、boolean、enum类型以及这些类型的数组;嵌套类型以及数组中的对象属性无法触发视图更新

写法
   @Entry
   @Component
    struct TestComponent {
    @State count: number = 0;

    build() {
        Column() {
          Text(this.count + '数字')
            .width('90%')

          Button('修改文本标题')
            .width('90%')
            .height('40')
            .onClick(() => {
                this.count += 1
            })

        }
        .width('100%')
        .height('100%')
       }
}
特点

2.@Prop 装饰器

@Prop 用于创建父子组件的单向数据传递,并且修饰的变量无须初始化

写法
@Entry
@Component
struct TaskManagePage {
  @State totalTask: number = 0
  @State finishTask: number = 0

  build() {
    Column({space: 10}){
      // 2.任务进度卡片
      TaskStatistics({totalTask: this.totalTask, finishTask: this.finishTask})
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F2F3')
  }
}
@Component
export default struct TaskStatistics {

  @Prop totalTask: number = 0
  @Prop finishTask: number = 0

  build() {
    Row() {
      Text('任务进度: ')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
      Stack() {
        Progress({
          value: this.finishTask,
          total: this.totalTask,
          type: ProgressType.Ring
        })
          .width(100)
        Row() {
          Text(this.finishTask.toString())
            .fontSize(24)
            .fontColor('#36D')
          Text(' / ' + this.totalTask.toString())
            .fontSize(24)
        }
      }
    }
    .card()
    .margin({top: 5, bottom: 10})
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}
特点

3. @Link 装饰器

@Link用于创建父子组件间的双向数据绑定

写法
@Entry
@Component
struct TaskManagePage {
  @State totalTask: number = 0
  @State finishTask: number = 0

  build() {
    Column({space: 10}){
      TaskList({totalTask: $totalTask, finishTask:$finishTask})
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F2F3')
  }
}
@Component
export default  struct TaskList {
  // 总任务数量
  @Link totalTask: number
  @Link finishTask: number

  idx: number = 1

  // 任务信息弹窗
  dialogController: CustomDialogController = new CustomDialogController({
    builder: TaskInfoDialog({onTaskConfirm: this.handleAddTask.bind(this)})
  })

  aboutToAppear(): void {
    // 查询任务列表
    console.log('TaskTag', '初始化组件, 查询任务列表')
    TaskModel.getTaskList()
      .then(tasks => {
        this.tasks = tasks
        // 更新任务状态
        this.handleTaskChange()
      })
  }

  handleTaskChange() {
    // 1. 更新任务总数量
    this.totalTask = this.tasks.length
    // 2. 更新已完成任务数量
    this.finishTask = this.tasks.filter(item => item.finished).length
  }

  handleAddTask(name: string) {
    // 1. 新增任务
    TaskModel.addTask(name)
      .then(id => {
        console.log('taskTag', '处理新增任务: ', name)
        // 回显到数组页面
        this.tasks.push(new TaskInfo(id,name))
        // 2. 更新任务完成状态
        this.handleTaskChange()
        // 3. 关闭对话框
        this.dialogController.close()
      })
      .catch((error: Error) => console.log('taskTag', '新增任务失败: ', name, JSON.stringify(error)))
  }

  // 任务数组
  @State tasks: TaskInfo[] = []
  build() {
    Column() {
      // 新增任务数组
      Button('新增任务')
        .width(200)
        .margin({bottom: 10})
        .onClick(()=> {
          // 打开新增表单对话框
          this.dialogController.open()
        })

      // 2. 任务列表
      List({space: 10}){
        ForEach(
          this.tasks,
          (item: TaskInfo, index) => {
            ListItem() {
              TaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)})
            }
            .swipeAction({end: this.DeleteButton(index, item.id)})
          }
        )
      }
      .width('100%')
      .layoutWeight(1)
      .alignListItem(ListItemAlign.Center)
    }
  }

 
}
特点:

4. @Provide 和 @Consume 装饰器

@Provide 和 @Consume 用于跨组件层级同步状态变量

写法
@Component
struct ProviderComponent {
    @Provide('key') fontSize: number = 16 // ('key')可以不加不加的话 两个声明属性要一样

    build() {
        // UI构建逻辑
    }
}

@Component
struct ConsumerComponent {
    @Consume('key')  fontSize: number // ('key')可以不加 不加的话 两个声明属性要一样

    build() {
        // UI构建逻辑
    }
}
特点:

5 @ObjkectLink 装饰器

@ObjectLink 用于观察和同步对象属性的变化。

写法
@Component
export  default  struct TaskItem {
  @ObjectLink item: TaskInfo
  @Prop onTaskChange: (item: TaskInfo) => void
  build() {
    Row() {
      if (this.item.finished) {
        Text(this.item.name)
          .finishedTask()
      }else {
        Text(this.item.name)
      }
      Checkbox()
        .select(this.item.finished)
        .onChange( async  val => {
          // 1. 更新当前任务状态
          TaskModel.updateTaskStatus(this.item.id, val)
            ?.then(() => {
              this.item.finished = val
            // 2.更新已完成任务数量
            this.onTaskChange(this.item)
          })
            .catch((error:Error) => console.log('taskTag', '更新任务状态失败, id = ', this.item.id, JSON.stringify(error)))
        })
    }
    .card()
    .justifyContent(FlexAlign.SpaceBetween)
  }
}
 @Observed
export default class TaskInfo {
  id: number = 0
  // 任务名称
  name: string = ''
  // 任务状态 是否完成
  finished: boolean = false

  constructor(id: number, name: string) {
    this.id = id
    this.name = name
    this.finished = false
  }
}
特点:

6. @Extend 和 @Style

@Extend(Text) // 继承模式,只能写在全局内
@Extend(Text) function priceText() {
   .fontColor('#F36D')
   .fontSize(18)
}
@Style // 全局公共样式
@Styles function filleScreen() {
    .width('100%')
    .height('100%')
    .backgroundColor('#EFEFEF')
    .padding(20)
}

7. @StorageProp

@StorageProp 是一个装饰器,用于在组件内部变量与
AppStorage 中指定属性之间建立单向数据同步。当你使用
@StorageProp(key) 装饰一个组件内的变量时,这个变量就会与
AppStorage 中对应
key 的属性绑定。这意味着,如果
AppStorage 中给定
key 的属性发生改变,这个改变会被同步到
@StorageProp 装饰的变量中,并覆盖掉本地的修改。但是,本地对
@StorageProp 变量的修改不会同步回

上一篇 下一篇

猜你喜欢

热点阅读