当前位置: 首页 > news >正文

#HarmonyOS篇:管理组件拥有的状态

官网链接 @Prop @Link等

@State

@State声明的变量,必须给初始值,否则编辑报错
不支持装饰Function类型。

@Prop

基本用法

@Prop装饰的变量允许本地修改,但修改不会同步回父组件。
子组件@Prop更新时,更新仅停留在当前子组件,不会同步回父组件。

不允许装饰Function类型

父组件传递的值 子组件不用@Prop接收也可以渲染,只不过子组件改值不会自动更新视图

使用a.b(this.object)形式调用,不会触发UI刷新

通过赋值添加 Proxy 代理 let score1 = this.score

class Score {value: number;constructor(value: number) {this.value = value;}static changeScore1(score:Score) {score.value += 1;}
}@Entry
@Component
struct Parent {@State score: Score = new Score(1);build() {Column({space:8}) {Text(`The value in Parent is ${this.score.value}.`).fontSize(30).fontColor(Color.Red)Child({ score: this.score })}.width('100%').height('100%')}
}@Component
struct Child {@Prop score: Score;changeScore2(score:Score) {score.value += 2;}build() {Column({space:8}) {Text(`The value in Child is ${this.score.value}.`).fontSize(30)Button(`changeScore1`).onClick(()=>{// 通过赋值添加 Proxy 代理let score1 = this.score;Score.changeScore1(score1);})Button(`changeScore2`).onClick(()=>{// 通过赋值添加 Proxy 代理let score2 = this.score;this.changeScore2(score2);})}}
}

@Link

注意事项
  • List item

@Link装饰器不建议在@x`Entry装饰的自定义组件中使用,否则编译时会抛出警告;若该自定义组件作为页面根节点使用,则会抛出运行时错误。

  • @Link装饰的变量禁止本地初始化,否则编译期会报错。

  • @Link装饰的变量的类型要和数据源类型保持一致,否则编译期会报错。同时,数据源必须是状态变量,否则框架会抛出运行时错误。

  • @Link装饰的变量仅能被状态变量初始化,不能使用常规变量初始化,否则编译期会给出告警,并在运行时崩溃

@Link name: string | undefined; ----支持联合类型

@Watch监听的写法

 @Link @Watch('onChangeSonToP') SonToParentText: string;onChangeSonToP() {console.info('111')}

@Provide @Consume 双向同步

 // 提供@Provide parentArg: string = ' 父组件提供--provide'// 获取@Consume parentArg: string;

@Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化

注意事项

@ObjectLink装饰的变量不能被赋值,如果要使用赋值操作,请使用@Prop。

@ObjectLink装饰的变量和数据源的关系是双向同步

@Observed装饰的类,如果其属性为非简单类型,比如class、Object或者数组,那么这些属性也需要被@Observed装饰,否则将观察不到这些属性的变化。

定义

从父组件初始化

必须指定。
初始化@ObjectLink装饰的变量必须同时满足以下场景:

  • 类型必须是@Observed装饰的class。
  • 初始化的数值需要是数组项,或者class的属性。
示例代码
@Observed
class Book {name: string;constructor(name: string) {this.name = name;}
}@Observed
class Bag {book: Book;constructor(book: Book) {this.book = book;}
}@Component
struct BookCard {@ObjectLink book: Book;build() {Column() {Text(`BookCard: ${this.book.name}`) // 可以观察到name的变化.width(320).margin(10).textAlign(TextAlign.Center)Button('change book.name').width(320).margin(10).onClick(() => {this.book.name = 'C++';})}}
}@Entry
@Component
struct Index {@State bag: Bag = new Bag(new Book('JS'));build() {Column() {Text(`Index: ${this.bag.book.name}`) // 无法观察到name的变化.width(320).margin(10).textAlign(TextAlign.Center)Button('change bag.book.name').width(320).margin(10).onClick(() => {this.bag.book.name = 'TS';})BookCard({ book: this.bag.book })}}
}

@Track

@Track是class对象的属性装饰器。当一个class对象是状态变量时,@Track装饰的属性发生变化,只会触发该属性关联的UI更新;如果class类中使用了@Track装饰器,则未被@Track装饰器装饰的属性不能在UI中使用,如果使用,会发生运行时报错。

class TrackLock {@Track name: string;@Track age: string;constructor(name: string, age: string) {this.name = namethis.age = age}
}class TrackNoLock {name1: string;age1: stringconstructor(name1: string, age1: string) {this.name1 = name1this.age1 = age1}
}@Component
export struct TrackTest {@State trackLock: TrackLock = new TrackLock('小明', '15')@State trackNoLock: TrackNoLock = new TrackNoLock('小明1', '18')isRender(index: number) {console.info(`Text ${index} is rendered`);return 50;}build() {Column() {Text('trackLock-测试')Text(this.trackLock.name).fontSize(this.isRender(1))Text(this.trackLock.age).fontSize(this.isRender(2))Text('trackNoLock-测试')Text(this.trackNoLock.name1).fontSize(this.isRender(3))Text(this.trackNoLock.age1).fontSize(this.isRender(4))Button('测试').onClick((event: ClickEvent) => {this.trackLock.name = '11'// 输入  Text 1 is rendered})Button('change logNotTrack.str1').onClick(() => {this.trackNoLock.name1 = '再见';// 输出Text 3 is renderedText 4 is rendered})}}
}

@Builder装饰器:自定义构建函数

arkUI提供轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递。开发者可将重复使用的UI元素抽象成函数,在build函数中调用。

@Builder装饰的函数也称为“自定义构建函数”。

封装可复用的UI结构

@LocalBuilder维持组件关系

注意事项

  • @LocalBuilder只能在所属组件内声明,不允许全局声明。

  • @LocalBuilder不能与内置装饰器或自定义装饰器一起使用。

  • 在自定义组件中,@LocalBuilder不能用来装饰静态函数。

== 允许在自定义组件内定义一个或多个@LocalBuilder函数,该函数被认为是该组件的私有、特殊类型的成员函数。==

@LocalBuilder和局部@Builder使用区别

跨组件传递局部@Builder函数时,会使用.bind(this)更改函数上下文,但这可能会导致组件的父子关系与状态管理的父子关系不一致。而@LocalBuilder无论是否使用.bind(this),都不会改变组件的父子关系,即@LocalBuilder中定义组件所属的父组件是确定的,无法被改变。

//----------------------------- 传递 父组件 Parentlabel: string = 'Parent';@LocalBuilderbuilderChild() {Text('Builder-child---' + this.label)}
// ------------------
//---------------------------- 使用 在父组件中使用Row() {Text('父')this.builderChild()}Child({ customBuilderParams: this.builderChild })
//-------------------------- 子组件接收 Childlabel: string = 'Child';@BuilderParam customBuilderParams: () => void

@BuilderParam装饰器:引用@Builder函数

@BuilderParam用于装饰指向@Builder方法的变量,通过调用@BuilderParam为组件增加特定功能。

如果不这样的话会导致所有自定义组件都增加此实例方法。

@BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化。

@Styles支持全局和局部 不支持传参数

@Extend仅支持全局定义 支持传递参数

@Require校验构造参数

当Child组件内使用@Require装饰器和@Prop、@State、@Provide、@BuilderParam、@Param和普通变量(无状态装饰器修饰的变量)结合使用时,父组件Index在构造Child时必须传参,否则编译不通过。

http://www.dtcms.com/a/581673.html

相关文章:

  • 网站开启速度慢网站建设项目外包合同范本
  • 苏州手机网站建设乐清市建设规划局网站
  • 从数据节点到决策基石:以太网温湿度压力传感器的系统价值重构
  • Greensea IQ-用于国防、商业和科学领域的机器人和水下技术
  • Spring 代理的选择
  • 构建可用于生产环境的AI智能体
  • CAN终端电阻的用处
  • 上海seo推广整站哪个网站的pc端是用vue做的
  • 应届生出来做网站还是做报纸好网站后台管理图片
  • [GDOUCTF 2023]泄露的伪装
  • AtCoder Educational DP Contest 刷题记录Ⅱ
  • 如何构建以数据驱动的现代软件架构
  • 如何禁止Chrome的重新启动即可更新窗口弹窗提示
  • 爱用建站 小程序镇江网站制作优化
  • 在Ubuntu中下载gcc
  • 杰理蓝牙耳机开发 -- SPP功能开发与应用
  • 【锦州通APP注册_登录安全-无验证方式导致安全隐患】
  • 网站建设属于哪个类目淘宝网站开发费用
  • Socket vs WebSocket
  • Java中BufferedImage转byte[]字节数组
  • day10 鹏哥C语言 操作符
  • 推广平台网站聊城网站建设推广
  • 政策东风下:卓玛儿童级健康腻子引领行业升级
  • Azure Storage Discovery(国际版)正式发布
  • 4、prometheus-服务发现k8s api-2
  • 立冬节气科学调养身心
  • 安徽省建设行业质量与安全协会网站网站建设拓客有什么方法
  • 【XR开发系列】2025 年 XR 开发入门,我该选择 Unity 还是 Unreal Engine?
  • 在wps软件的word中使用js宏命令设置表格背景色
  • 怎样写网站文案零食网站建设前的市场分析