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

【ArkTS-装饰器】

ArkTS-装饰器

  • ■ ArkTS 装饰器
    • ■ @Entry 页面的生命周期
    • ■ @Component 自定义组件
      • ■ 1. Component装饰的struct称为UI组件。主要特征:
      • ■ 2. component内部还可以调用另外一个component 示例
    • ■ @Builder装饰器: 自定义构建函数可复用 UI 片段
      • ■ 简单的无参数@Builder
      • ■ 带参数的@Builder
      • ■ 包含逻辑的@Builder
      • ■ 包含循环的@Builder
      • ■ 使用列表@Builder
      • ■ 全局定义@Builder
      • ■ @Builder 与组件交互
      • ■ @BuilderParam:Builder 作为参数
      • ■ @Builder 与状态管理
    • ■ 传递参数
      • ■ 1. 按值传递参数
      • ■ 2. 按引用传递参数
    • ■ @State状态装饰器
      • ■ 示例 -状态改变时 UI会发生对应的渲染改变
    • ■ @Prop装饰器:父子单向同步
      • ■ 示例功能说明:
    • ■ @Track装饰器:// 使用@Track装饰器标记需要跟踪的字段
    • ■ @Observed //定义一个被观察的类,
    • ■ @Link 建立双向数据绑定,任何一方对数据的修改都会同步到另一方
    • ■ @ObjectLink 与父组件共享同一对象引用
    • ■ @Watch
    • ■ @LocalBuilder装饰器: 维持组件父子关系
    • ■ @AnimatableExtend装饰器:定义可动画属性
    • ■ @Require装饰器:校验构造传参
    • ■ @Reusable装饰器:组件复用
    • ■ @Watch装饰器:状态变量更改通知
    • ■ @Styles装饰器:定义组件重用样式
    • ■ @Extend装饰器:定义扩展组件样式
    • ■ @Monitor装饰器:状态变量修改监听
    • ■ @Param:组件外部输入
    • ■ @Once:初始化同步一次
    • ■ @Event装饰器:规范组件输出
    • ■ @Provider装饰器和 @Consumer装饰器:跨组件层级双向同步
    • ■ @Type装饰器:标记类属性的类型

■ ArkTS 装饰器

■ @Entry 页面的生命周期

一个页面有且仅有一个@Entry入口。

■ @Component 自定义组件

HarmonyOS的生命周期可以分为 @Compnent的生命周期和 @Entry的生命周期 也就是自定义组件的生命周期和页面的生命周期。
@Component和@Entry,ArkTS通过这两个关键字来装饰struct声明的数据结构,这个过程我们称为自定义组件。
组件内部需要提供一个build函数,我们在该函数体内按照链式调用的方式来描述整个页面的UI布局。

■ 1. Component装饰的struct称为UI组件。主要特征:

  1. 一个页面有且仅有一个@Entry入口。
  2. 一个页面可以包含一个或多个component;
  3. 每个component都必须实现 build 方法来更新UI;
  4. 一个component内部还可以调用另外一个component;

■ 2. component内部还可以调用另外一个component 示例

示例

@Entry       //一个页面有且仅有一个@Entry入口。
@Component   //一个页面可以包含一个或多个component;
struct MainComponent {build() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text('Black is MainComponent').fontSize(26).fontColor(Color.Black).height(50)SubComponent()  //调用}.width('100%').height('100%')}
}@Component  //一个页面可以包含一个或多个component;
struct SubComponent {build() {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Text('Red is SubComponent').fontSize(26).fontWeight(500).fontColor(Color.Red)}.width('100%')}
}

在这里插入图片描述

■ @Builder装饰器: 自定义构建函数可复用 UI 片段

■ 简单的无参数@Builder

■ 带参数的@Builder

■ 包含逻辑的@Builder

■ 包含循环的@Builder

■ 使用列表@Builder

@Entry
@Component
struct BuilderExample {// 简单的无参数Builder@BuildersimpleTextBuilder() {Text('Hello World').fontSize(30).fontWeight(FontWeight.Bold).fontColor(Color.Blue)}// 带参数的Builder@BuilderparameterizedBuilder(text: string, size: number, color: Color) {Text(text).fontSize(size).fontColor(color).fontWeight(FontWeight.Medium)}// 包含逻辑的Builder@BuilderconditionalBuilder(score: number) {if (score >= 90) {Text('优秀').fontColor(Color.Green)} else if (score >= 60) {Text('及格').fontColor(Color.Orange)} else {Text('不及格').fontColor(Color.Red)}}// 包含循环的Builder@BuilderlistBuilder(items: string[]) {Column() {ForEach(items, (item: string) => {Text(item).fontSize(16).margin(5)})}}build() {Column({ space: 20 }) {// 使用无参数Builderthis.simpleTextBuilder()// 使用带参数Builderthis.parameterizedBuilder('自定义文本', 24, Color.Red)Divider()// 使用条件Builderthis.conditionalBuilder(85)this.conditionalBuilder(55)Divider()// 使用列表Builderthis.listBuilder(['项目1', '项目2', '项目3', '项目4'])}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}
}

■ 全局定义@Builder

// 全局Builder定义
@Builder
function GlobalCard(title: string, content: string) {Column() {Text(title).fontSize(20).fontWeight(FontWeight.Bold).margin({ bottom: 10 })Text(content).fontSize(16).fontColor(Color.Gray)}.padding(15).backgroundColor(Color.White).border({ width: 1, color: Color.Gray }).borderRadius(8).width('90%').margin({ bottom: 10 })
}@Entry
@Component
struct GlobalBuilderExample {build() {Column() {Text('全局Builder示例').fontSize(24).fontWeight(FontWeight.Bold).margin({ bottom: 20 })// 使用全局BuilderGlobalCard('标题1', '这是第一个卡片的内容')GlobalCard('标题2', '这是第二个卡片的内容,内容可以更长一些')GlobalCard('标题3', '第三个卡片的内容')}.width('100%').height('100%').padding(20).backgroundColor('#F5F5F5').justifyContent(FlexAlign.Start)}
}

■ @Builder 与组件交互

@Entry
@Component
struct InteractiveBuilderExample {@State count: number = 0@State text: string = '初始文本'// Builder访问组件状态@BuildercounterBuilder() {Row() {Button('减少').onClick(() => {this.count--})Text(`计数: ${this.count}`).fontSize(18).margin(10)Button('增加').onClick(() => {this.count++})}}// Builder访问组件方法@BuildertextInputBuilder() {Column() {TextInput({ text: this.text }).onChange((value: string) => {this.text = value}).width(200)Text(`当前文本: ${this.text}`).fontSize(16).margin({ top: 10 })}}build() {Column({ space: 20 }) {Text('Builder与组件交互示例').fontSize(24).fontWeight(FontWeight.Bold)this.counterBuilder()this.textInputBuilder()}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}
}

在这里插入图片描述

■ @BuilderParam:Builder 作为参数

  • @BuilderParam 允许将 Builder 作为参数传递给组件,实现高度可定制的 UI:
@Component
struct CustomCard {// 使用@BuilderParam接收Builder作为参数@BuilderParam headerBuilder: () => void@BuilderParam contentBuilder: () => voidbuild() {Column() {// 使用传入的headerBuilderthis.headerBuilder()Divider().margin(10)// 使用传入的contentBuilderthis.contentBuilder()}.padding(15).border({ width: 1, color: Color.Gray }).borderRadius(8).width('90%').margin(10)}
}@Entry
@Component
struct BuilderParamExample {@BuildercustomHeader() {Row() {Image($r('app.media.icon')).width(30).height(30).margin({ right: 10 })Text('自定义标题').fontSize(18).fontWeight(FontWeight.Bold)}}@BuildercustomContent() {Text('这是自定义的内容区域,可以包含任何UI组件和布局').fontSize(14).fontColor(Color.Gray)}@BuilderanotherHeader() {Text('另一个标题样式').fontSize(20).fontColor(Color.Blue).fontWeight(FontWeight.Bold)}@BuilderanotherContent() {Column() {Text('多行内容')Text('第二行内容')Button('按钮').margin({ top: 10 })}}build() {Column() {Text('@BuilderParam示例').fontSize(24).fontWeight(FontWeight.Bold).margin({ bottom: 20 })// 使用CustomCard组件,传入不同的BuilderCustomCard({headerBuilder: this.customHeader,contentBuilder: this.customContent})CustomCard({headerBuilder: this.anotherHeader,contentBuilder: this.anotherContent})}.width('100%').height('100%').padding(20).backgroundColor('#F5F5F5').justifyContent(FlexAlign.Start)}
}

■ @Builder 与状态管理

@Entry
@Component
struct AdvancedBuilderExample {@State items: string[] = ['苹果', '香蕉', '橙子', '葡萄']@State isEditing: boolean = false// 动态生成列表项的Builder@BuilderitemListBuilder() {Column() {ForEach(this.items, (item: string, index: number) => {this.listItemBuilder(item, index)})}}// 单个列表项的Builder@BuilderlistItemBuilder(item: string, index: number) {Row() {Text(item).fontSize(18).layoutWeight(1)if (this.isEditing) {Button('删除').onClick(() => {this.items.splice(index, 1)this.items = [...this.items] // 触发状态更新}).backgroundColor(Color.Red).fontColor(Color.White)}}.padding(10).border({ width: 1, color: Color.Gray }).borderRadius(4).margin({ bottom: 5 }).width('100%')}build() {Column({ space: 20 }) {Text('高级Builder示例').fontSize(24).fontWeight(FontWeight.Bold)this.itemListBuilder()Row({ space: 10 }) {Button(this.isEditing ? '完成编辑' : '编辑列表').onClick(() => {this.isEditing = !this.isEditing})Button('添加项目').onClick(() => {const newItem = `项目${this.items.length + 1}`this.items = [...this.items, newItem]})}}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Start)}
}

在这里插入图片描述

■ 传递参数

■ 1. 按值传递参数

状态变量的改变不会引起@Builder方法内的UI刷新

@Builder 
function overBuilder(paramA1: string) {Row() {Text(`UseStateVarByValue: ${paramA1} `)}
}
@Entry
@Component
struct Parent {@State ppppp: string = 'Hello';build() {Column() {overBuilder(this.ppppp)}}
}

■ 2. 按引用传递参数

按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。

class Tmp {paramA1: string = '';
}@Builder 
function overBuilder(params: Tmp) {Row() {Text(`UseStateVarByReference: ${params.paramA1} `)}
}
@Entry
@Component
struct Parent {@State label: string = 'Hello';build() {Column() {// 在父组件中调用overBuilder组件时,// 把this.label通过引用传递的方式传给overBuilder组件。overBuilder({ paramA1: this.label })Button('Click me').onClick(() => {// 单击Click me后,UI文本从Hello更改为ArkUI。this.label = 'ArkUI';})}}
}

■ @State状态装饰器

@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。
当状态改变时,UI会发生对应的渲染改变。

■ 示例 -状态改变时 UI会发生对应的渲染改变

@Entry
@Component
struct CounterExample {// 使用@State装饰器声明一个状态变量count,初始值为0// 当count的值发生变化时,会触发UI重新渲染@State count: number = 0// 构建函数,定义UI布局build() {// 垂直布局容器,设置对齐方式和间距Column({ space: 20 }) {// 显示计数器当前值Text(`当前计数: ${this.count}`).fontSize(30).fontWeight(FontWeight.Bold).fontColor(Color.Blue)// 增加计数按钮Button('增加 +1').onClick(() => {// 点击按钮时,count值增加1// 由于count是@State变量,UI会自动更新this.count++}).width(200).height(50).backgroundColor(Color.Green)// 减少计数按钮Button('减少 -1').onClick(() => {// 点击按钮时,count值减少1this.count--}).width(200).height(50).backgroundColor(Color.Orange)// 重置计数器按钮Button('重置').onClick(() => {// 点击按钮时,将count重置为0this.count = 0}).width(200).height(50).backgroundColor(Color.Red)}// 设置Column容器的宽度、高度和对齐方式.width('100%').height('100%').justifyContent(FlexAlign.Center)}
}

在这里插入图片描述

■ @Prop装饰器:父子单向同步

  • 单向数据流:数据从父组件流向子组件,子组件不能直接修改父组件的数据
  • 同步更新:当父组件的数据变化时,子组件的 @Prop 变量会自动更新
  • 局部修改:子组件可以修改 @Prop 变量的值,但不会影响父组件
  • 类型一致性:@Prop 变量的类型必须与父组件传递的数据类型一致

■ 示例功能说明:

在这里插入图片描述

import { ToolBar } from '@ohos.arkui.advanced.ToolBar';@Entry
@Component
struct ParentComponent {// 父组件的状态变量@State parentCount: number = 0@State parentMessage: string = "Hello from Parent"build() {Column({ space: 20 }) {// 显示父组件的状态Text("父组件状态").fontSize(20).fontWeight(FontWeight.Bold)Text(`计数: ${this.parentCount}`).fontSize(18)Text(`消息: ${this.parentMessage}`).fontSize(18)// 修改父组件状态的按钮Button('父组件计数+1').onClick(() => {this.parentCount++}).width(200)Button('修改父组件消息').onClick(() => {this.parentMessage = "父组件消息已更新 " + new Date().toLocaleTimeString()}).width(200)Divider().margin(20)// 使用子组件,并通过构造函数传递@Prop数据ChildComponent({count: this.parentCount,message: this.parentMessage})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}
}@Component
struct ChildComponent {// 使用@Prop装饰器接收父组件传递的数据// 当父组件的parentCount变化时,会自动更新这里的count@Prop count: number// 当父组件的parentMessage变化时,会自动更新这里的message@Prop message: string// 子组件本地的状态变量@State localCount: number = 0build() {Column({ space: 15 }) {Text("子组件状态").fontSize(20).fontWeight(FontWeight.Bold).fontColor(Color.Blue)Text(`从父组件接收的计数: ${this.count}`).fontSize(16)Text(`从父组件接收的消息: ${this.message}`).fontSize(16)// .fontColor(Color.Green)Text(`子组件本地计数: ${this.localCount}`).fontSize(16)// .fontColor(Color.Purple)Divider().margin(10)// 修改子组件本地状态的按钮Button('子组件本地计数+1').onClick(() => {this.localCount++}).width(200)// 尝试修改@Prop变量(不会影响父组件)Button('尝试修改@Prop计数').onClick(() => {// 这个修改只会影响子组件内部,不会同步回父组件this.count += 10console.log("子组件修改了@Prop count,但不会影响父组件")}).width(200)}.padding(15).border({ width: 1, color: Color.Gray }).borderRadius(10).margin({ top: 20 })}
}

■ @Track装饰器:// 使用@Track装饰器标记需要跟踪的字段

  • 精确跟踪:只跟踪被 @Track 装饰的字段,其他字段的变化不会触发UI更新
  • 性能优化:避免不必要的渲染,提高应用性能
  • 必须与 @Observed 配合使用:@Track 只能用于被 @Observed 装饰的类中的字段
  • 深度观察:对于嵌套对象,需要每一层都使用 @Observed 和 @Track

■ @Observed //定义一个被观察的类,

// 定义一个被观察的类,使用@Observed装饰器
@Observed
class UserInfo {// 使用@Track装饰器标记需要跟踪的字段@Track name: string@Track age: number// 这个字段没有使用@Track,变化不会触发UI更新internalId: number = 0constructor(name: string, age: number) {this.name = namethis.age = age}
}

■ @Link 建立双向数据绑定,任何一方对数据的修改都会同步到另一方

  • 双向数据绑定:父子组件共享同一数据源,任何一方的修改都会同步到另一方.
  • 必须使用$符号:在父组件中传递 @Link 变量时,必须使用 $variableName 语法.
  • 类型一致性:@Link 变量的类型必须与父组件中的状态变量类型一致.
  • 无需初始化:@Link 变量不能在子组件中初始化,必须从父组件传递.

■ @ObjectLink 与父组件共享同一对象引用

// 使用@ObjectLink装饰器接收对象,与父组件共享同一对象引用

■ @Watch

@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用.

@Entry
@Component
struct AdvancedWatchExample {@State @Watch('onMultipleChange') value1: number = 0@State @Watch('onMultipleChange') value2: number = 0@State message: string = ""// 监听多个状态变化的回调函数onMultipleChange() {this.message = `值1: ${this.value1},2: ${this.value2}, 总和: ${this.value1 + this.value2}`}build() {Column({ space: 10 }) {Text(this.message).fontSize(16)Button('增加值1').onClick(() => {this.value1 += 1})Button('增加值2').onClick(() => {this.value2 += 1})}}
}

在这里插入图片描述

■ @LocalBuilder装饰器: 维持组件父子关系

■ @AnimatableExtend装饰器:定义可动画属性

■ @Require装饰器:校验构造传参

■ @Reusable装饰器:组件复用

■ @Watch装饰器:状态变量更改通知

■ @Styles装饰器:定义组件重用样式

■ @Extend装饰器:定义扩展组件样式

■ @Monitor装饰器:状态变量修改监听

■ @Param:组件外部输入

■ @Once:初始化同步一次

■ @Event装饰器:规范组件输出

■ @Provider装饰器和 @Consumer装饰器:跨组件层级双向同步

■ @Type装饰器:标记类属性的类型


文章转载自:

http://xRmnq0uF.wnpps.cn
http://hoV9NjCa.wnpps.cn
http://LA8klDTC.wnpps.cn
http://Adjq9p7O.wnpps.cn
http://RzFIU2pd.wnpps.cn
http://22HgyPWg.wnpps.cn
http://7AVpfDEH.wnpps.cn
http://QOtrejVC.wnpps.cn
http://15NXCPYz.wnpps.cn
http://4eIr8uNX.wnpps.cn
http://htzFicyB.wnpps.cn
http://DzoCH1oG.wnpps.cn
http://YKLK1arc.wnpps.cn
http://Kb3H0iap.wnpps.cn
http://CjGqb84n.wnpps.cn
http://Tpiliuc0.wnpps.cn
http://IeCRm0kM.wnpps.cn
http://dXYFgXyS.wnpps.cn
http://et0fh7Xd.wnpps.cn
http://0jppkmFu.wnpps.cn
http://pzKdkK8f.wnpps.cn
http://mnETG5j2.wnpps.cn
http://DUm5nKsq.wnpps.cn
http://N0uQk9nu.wnpps.cn
http://UjG84mqb.wnpps.cn
http://nqk7QTzE.wnpps.cn
http://dpVCydOk.wnpps.cn
http://BF0nlutB.wnpps.cn
http://CSckhN4K.wnpps.cn
http://WQUQWsys.wnpps.cn
http://www.dtcms.com/a/374997.html

相关文章:

  • XSS漏洞检测和利用
  • Vue3 生命周期函数
  • Flask/Django 生产部署:Gunicorn vs Nginx,Windows 与 Linux 实战指引
  • 从 Row 到 WaterFlow:鸿蒙应用开发ArkUI布局全家桶教程
  • 开发避坑指南(44):Mybatis-plus QueryWrapper and()拼接嵌套复杂条件的技巧
  • 消息队列(MQ)初级入门:详解RabbitMQ与Kafka
  • R语言对excel中多个sheet子表批量进行地理探测器计算
  • 开讲啦| MBSE公开课:第六集 MBSE远期目标与总结(完结)
  • 实习项目包装--HTTP 协议和 Web API
  • linux升级系统,重启出现Minimal BASH-like line editingis supported
  • ARM架构---指令集分类、内核组成,RAM与ROM的分类、工作模式、异常处理机制、立即数、s后缀、指令说明、汇编和 C 函数的相互调用
  • Qwen3微调教程:从零开始训练你的定制语言模型
  • 本地一键部署IndexTTS2,生成情绪饱满的语音,支持Windows和Mac
  • VMware虚拟机CentOS磁盘扩容完整指南(解决growpart报错 LVM扩容)
  • 【增删改查操作】
  • MySQL 多表操作与复杂查询:深入理解多表关系和高级查询
  • 网络相关知识整理
  • 提升网站用户体验的方法 | 网站优化与用户界面设计
  • CSS的文本样式
  • Flex布局——详解
  • 深度解析CSS单位与媒体查询:构建现代化响应式布局的核心技术
  • 项目组件抽离封装思路
  • Elasticsearch面试精讲 Day 13:索引生命周期管理ILM
  • 【MySQL】从零开始了解数据库开发 --- 数据类型
  • ElasticSearch复习指南:从零搭建一个商品搜索案例
  • 宋红康 JVM 笔记 Day15|垃圾回收相关算法
  • 【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
  • 【python实用小脚本-211】[硬件互联] 桌面壁纸×Python梦幻联动|用10行代码实现“开机盲盒”自动化改造实录(建议收藏)
  • 前端安全攻防:XSS, CSRF 等常见威胁的防范与检测指南
  • 算法题(203):矩阵最小路径和