学习鸿蒙基础(6)

一、@Prop属性 父------>子 单向同步

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。@Prop装饰的变量和父组件建立单向的同步关系。@Prop变量允许在本地修改,但修改后的变化不会同步回父组件。当父组件中的数据源更改时,与之相关的@Prop装饰的变量都会自动更新。如果子组件已经在本地修改了@Prop装饰的相关变量值,而在父组件中对应的@State装饰的变量被修改后,子组件本地修改的@Prop装饰的相关变量值将被覆盖。

注意:

@Prop变量装饰器允许装饰的变量类型只有:string、number、boolean、enum类型

二、@Link属性 父------>子 双向同步

子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定@Link变量装饰器说明允许装饰的变量类型Object、class、string、number、boolean、enum类型,以及这些类型的数组。类型必须被指定,且和双向绑定状态变量的类型相同。不支持any,不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类型。

被装饰变量的初始值:无。

TypeScript 复制代码
@Entry
@Component
struct PageLink {
  @State message: string = 'Hello World'

  @State isShow:boolean =false

  build() {
    Row() {
      Column() {
        nav({isShow:$isShow})
        if(this.isShow){
          textrr()
        }
      }
      .height('100%')
    }
  }
}

@Component
struct nav{
  @Link isShow:boolean
  build(){
    Row(){
      Button("show").onClick(v=>{
          this.isShow=!this.isShow
      }).margin(20)
    }
  }
}
@Component
struct textrr{
  build(){
    Row(){
      Text("你好").margin(60)
    }
  }
}

三、嵌套类对象属性变化

@ObiectLink变量装饰器和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步。被@observed装饰的类,可以被观察到属性的变化。

子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class obiect中的属性,这个属性同样也需要被@observed装饰。。单独使用@Observed是没有任何作用的,需要搭配@obiectLink或者@Prop使用

@Observed类装饰器:装饰class。需要放在class的定义前,使用new创建类对象

@ObiectLink变量装饰器:不与父组件中的任何类型同步变量。

允许装饰的变量类型:必须为被@Observed装饰的class实例,必须指定类型。不支持简单类型,可以使用@Prop。@ObiectLink的属性是可以改变的,但是变量的分配是不允许的,也就是说这个装。饰器装饰变量是只读的,不能被改变。

TypeScript 复制代码
import myList from '../components/myListObserved'
import Item from '../model/ItemFlag'
@Entry
@Component
struct PageObserved {
  @State text: string = ''
  @State list: Item [] = [
    new Item(Date.now(), "房子"),
    new Item(Date.now(), "车子")
  ]

  build() {
    Row() {
      Column() {
        Row(){
          CheckboxGroup({group:"checkBoxGroup"})
          Text("全选")
          Button("删除").onClick(v=>{
                this.list=this.list.filter(v=>!v.isChecked)
          }).margin({left:"20"}).backgroundColor(Color.Red)
        }.width("100%").margin({top:"10",left:'20'})
        Row() {
          TextInput({ text: this.text }).width(250).onChange((value) => {
            this.text = value
          })
          Button("增加").onClick(() => {
            this.list.push(new Item(Date.now(), this.text))
            this.text = ""
          }).margin(10)
        }.width("100%").justifyContent(FlexAlign.SpaceBetween).margin(10)

        List() {
          ForEach(this.list, (item, index) => {
            ListItem() {
              myList({ item, index, list: this.list})
            }.margin(10)
          })
        }.layoutWeight(1).divider({
          strokeWidth: 1,
          color: Color.Blue,
          startMargin: 10,
          endMargin: 10
        })
        .width('100%')
      }
    }
    .height('100%')
  }
}
TypeScript 复制代码
import Item from '../model/ItemFlag';
//自定义组件  组件与组件之间是隔离的
@Component
struct myListObserved {
  @ObjectLink item: Item;
  private index: number;
  private list: Item [];


  build() {
    Row() {
      Checkbox({group:"checkBoxGroup"}).select(this.item.isChecked).onChange(v=>{
        this.item.isChecked=v
        console.log(JSON.stringify(this.item))
      })
      Text(this.item.text).fontSize(20).decoration(
        {type:this.item.isChecked?TextDecorationType.Underline:TextDecorationType.None,
          color:Color.Blue}
      )
      Button("删除").backgroundColor(Color.Red).onClick(() => {
        this.list.splice(this.index, 1)
      })
    }.justifyContent(FlexAlign.SpaceBetween).width("100%")
  }
}

export default myListObserved
TypeScript 复制代码
@Observed class ItemFlag {
  id: number;
  text: string;
  isChecked:boolean;

  constructor(id: number, text: string,isChecked=false) {
    this.id = id
    this.text = text
    this.isChecked=isChecked
  }
}

export  default ItemFlag

四、与后代组件双向同步

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递机制的束缚,实现跨层级传递。

其中@Provide装饰的变量是在祖先节点中,可以理解为被"提供"给后代的状态变量。@Consume装饰的变量是在后代组件中,去"消费(绑定)"祖先节点提供的变量。

1.装饰器参数:别名:常量字符串,可选。如果指定了别名,则通过别名来绑定变量,如果未指定别名,则通过变量名绑定变量。

2.同步类型:双向同步。从@Provide变量到所有@Consume变量以及相反的方向的数据同步。双向同步的操作与@State和@Link的组合相同。

3.允许装饰的变量类:Object、class、string、number、boolean、enum类型,以及这些类型的数组。不支持any.不支持简单类型和复杂类型的联合类型,不允许使用undefined和null。必须指定类型@Provide变量的@Consume变量的类型必须相同。说明不支持Length、ResourceStr、ResourceColor类型,Length、ResourceStr、ResourceColor为简单类型和复杂类型的联合类。

TypeScript 复制代码
@Entry
@Component
struct PageProvide {
  @Provide('msg') message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text("爷爷"+this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
        Fahter()
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct Fahter{
  @Consume message:string
  build(){
    Column(){
        Text("爸爸"+this.message).fontSize(50)
          .fontWeight(FontWeight.Bold)
      Son()
    }
  }
}

@Component
struct Son{
  @Consume msg:string
  message:string ="nn"
  build(){
    Column(){
      Text("儿子"+this.msg).fontSize(50)
        .fontWeight(FontWeight.Bold)
      Button("gaibian").onClick(v=>{
         this.msg="love world"
      })
    }
  }
}
相关推荐
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意4 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习