学习鸿蒙的第五课(状态管理@prop@link@Provide 装饰器)

  1. @prop 单向同步

    允许装饰的变量类型 @prpo只支持string,number、boolean、enum类型

​ 父组件是对象类型,子组件是对象属性

​ 不可以是数组、any

​ 不允许子组件初始化

  1. @Link 双向同步

    父子类型一致:string,number,boolean、enum、object、class,以及他们的数组

​ 数组中元素增删改都会引起刷新

​ 嵌套类型以及数组中的对象属性无法触发视图更新

​ 不允许子组件初始化

@Provide 和Cousume可以夸组件提供类似于@state和@link装饰器的双向同步(类似于vue中的发布和订阅)

// @ts-nocheck

/**
 * 任务条数量统计
 */
class Task {
  static id:number = 1
  name:string = `任务${Task.id++}`
  finished: boolean = false
}

class StartInfo{
  totalTask:number = 0
  finishTask:number = 0
}

// 统一的卡片样式
@Styles function card(){
  .width('90%')
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(15)
  .shadow({redius: 6, color:'#1F000000', offsetX:2, offsetY:4 })
}

// 任务完成样式
@Extend(Text) function finishTask(){
  .decoration({type:TextDecorationType.LineThrough})
  .fontColor('#B1B2B1')
}
@Component
struct TaskProgress {
  @Prop finishTask:number
  @Prop totalTask:number
  build() {
    Row() {
      Text('任务进度:')
        .fontWeight(FontWeight.Bold)
        .fontSize(30)
      Stack() {
        Progress({
          value: this.finishTask,
          total: this.totalTask,
          type: ProgressType.ScaleRing
        })
          .width(100)
        Row() {
          Text(this.finishTask.toString())
            .fontSize(30)
            .fontWeight(FontWeight.Bold)
          Text(' / ' + this.totalTask.toString())
            .fontSize(24)
            .fontWeight(FontWeight.Bold)
        }
      }

    }
    .justifyContent(FlexAlign.SpaceEvenly)
    .card()
    .margin({ top: 20, bottom: 10 })
  }
}

@Component
struct  TaskList{
  // @Link finishTask:number
  // @Link totalTask:number
  @Link stat:StartInfo
  // 任务数组
  @State taskList: Task[] = []
  build() {
    Column(){
      Button('新增任务')
        .width(200)
        .onClick(() => {
          this.taskList.push(new Task())
          this.handleTaskChange()
        })
        .margin({bottom:20})
      List({space:10}){
        ForEach(
          this.taskList,
          (task:Task,index)=>{
            ListItem(){
              Row(){
                Text(task.name)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                Checkbox()
                  .select(task.finished)
                  .onChange((val)=>{
                    task.finished = val
                    this.handleTaskChange()
                  })
              }
              .card()
              .margin({left:20})
              .justifyContent(FlexAlign.SpaceBetween)
            }
            .swipeAction({end:this.DeleteButton(index)})
          }
        )
      }
      .layoutWeight(1)
    }
  }
  @Builder DeleteButton(index:number){
    Button(){
      Image($r("app.media.app_icon"))
        .width(20)
        .height(20)
    }
    .type(ButtonType.Circle)
    .width(40)
    .height(40)
    .margin(20)
    .onClick(()=>{

      this.taskList.splice(index,1)
      this.handleTaskChange()
    })
  }
  handleTaskChange(){
    // 更新任务数量
    this.stat.totalTask = this.taskList.length
    // 更新已完成任务数量
    this.stat.finishTask = this.taskList.filter((item)=>item.finished).length
  }
}
@Entry
@Component
struct PropPage {
  // // 总任务数量
  // @State totalTask: number = 0
  //
  // //已完成任务数量
  // @State finishTask: number = 0
  @State stat: StatInfo = new StartInfo()

  build() {
    Column({ space: 10 }) {
      TaskProgress({totalTask:this.stat.totalTask,finishTask:this.stat.finishTask})
      // Link是引用类型,必须用特殊符号隔开
      TaskList({stat:$stat})
    }

    .width('100%')
    .height('100%')
    .backgroundColor("#F1F2F3")
  }


}



  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值