OpenHarmony 入门——ArkUI自定义组件的基础语法(一)

news2024/9/22 0:59:20

文章大纲

  • 引言
  • 一、自定义组件的基本语法
    • 1、@Component 装饰器 和 @Entry 装饰器
    • 2、build函数
    • 3、@Reuseable
    • 4、定义成员函数/变量
  • 二、自定义组件的使用

引言

在OpenHarmony 系统里ArkUI子系统显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与UI分离,后续版本演进等因素。本文基本就是把官网文档重新整理了下。

一、自定义组件的基本语法

在OpenHarmony定义一个自定义组件语法很简单,通常来说只需要三步:

  • 定义一个被@Component 装饰器修饰的struct类型的自定义组件名
  • 在这个自定义组件的代码块内实现build函数
@Component
struct MyComponent {
  build() {
  }
}

1、@Component 装饰器 和 @Entry 装饰器

@Component 装饰器像其他一些装饰器一样是华为的ArkTS语言(基于原生TypeScript的扩展)开发的机制,编译时会自动生成一些“胶水代码”完成一些相应的任务,比如说@State背后的原理就类似于观察者模式的应用,@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后且实现了build方法描述UI结构后才具备组件化的能力,一个struct只能被一个@Component装饰。@Component可以接受一个可选的bool类型参数。

//是否开启组件冻结。
@Entry
@Component({ freezeWhenInactive: true })
struct MyComponent {
}

并不是每一个组件都必须使用@Entry 装饰器,只有把这个自定义组件将作为UI页面的入口时才需要使用@Entry修饰。在单个UI页面中最多可以使用@Entry装饰一个自定义组件。@Entry可选参数:
在这里插入图片描述

从API version 10开始,@Entry可以接受一个可选的LocalStorage的参数或者一个可选的EntryOptions参数。

class PropB {
 code: number;
 constructor(code: number) {
   this.code = code;
 }
}
// 创建新实例并使用给定对象初始化
let para: Record<string, number> = { 'PropA': 47 };
let storage: LocalStorage = new LocalStorage(para);
storage.setOrCreate('PropB', new PropB(50));

@Component
struct Child {
 // @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定
 @LocalStorageLink('PropA') childLinkNumber: number = 1;
 // @LocalStorageLink变量装饰器与LocalStorage中的'PropB'属性建立双向绑定
 @LocalStorageLink('PropB') childLinkObject: PropB = new PropB(0);
 build() {
   Column() {
     Button(`Child from LocalStorage ${this.childLinkNumber}`) // 更改将同步至LocalStorage中的'PropA'以及Parent.parentLinkNumber
       .onClick(() => {
         this.childLinkNumber += 1;
       })
     Button(`Child from LocalStorage ${this.childLinkObject.code}`) // 更改将同步至LocalStorage中的'PropB'以及Parent.parentLinkObject.code
       .onClick(() => {
         this.childLinkObject.code += 1;
       })
   }
 }
}
// 使LocalStorage可从@Component组件访问
@Entry(storage)
@Component
struct CompA {
 // @LocalStorageLink变量装饰器与LocalStorage中的'PropA'属性建立双向绑定
 @LocalStorageLink('PropA') parentLinkNumber: number = 1;
 // @LocalStorageLink变量装饰器与LocalStorage中的'PropB'属性建立双向绑定
 @LocalStorageLink('PropB') parentLinkObject: PropB = new PropB(0);

 build() {
   Column({ space: 15 }) {
     Button(`Parent from LocalStorage ${this.parentLinkNumber}`) // initial value from LocalStorage will be 47, because 'PropA' initialized already
       .onClick(() => {
         this.parentLinkNumber += 1;
       })

     Button(`Parent from LocalStorage ${this.parentLinkObject.code}`) // initial value from LocalStorage will be 50, because 'PropB' initialized already
       .onClick(() => {
         this.parentLinkObject.code += 1;
       })
     // @Component子组件自动获得对CompA LocalStorage实例的访问权限。
     Child()
   }
 }
}

2、build函数

build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。同时build函数里有一些约束规则:

  • @Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。 @Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。

  • 不允许声明本地变量或者本地代码块(作用域),反例如下。

    build() {
      // 反例:不允许声明本地变量
      let a: number = 1;
      //反例
      {
      }
    }
    
  • 不允许在UI描述里直接使用console.info,但允许在函数里使用。

  • 不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值

@Component
struct ParentComponent {
  doSomeCalculations() {
  }
  calcTextValue(): string {
    return 'Hello World';
  }
  @Builder doSomeRender() {
    Text(`Hello World`)
  }
  build() {
    Column() {
      // 反例:不能调用没有用@Builder装饰的方法
      this.doSomeCalculations();
      // 正例:可以调用
      this.doSomeRender();
      // 正例:参数可以为调用TS方法的返回值
      Text(this.calcTextValue())
    }
  }
}
  • 不允许使用switch语法,如果需要使用条件判断,请使用if;也不允许使用三元表达式。
  • 不允许直接改变状态变量
@Component
struct CompA {
  @State col1: Color = Color.Yellow;
  @State col2: Color = Color.Green;
  @State count: number = 1;
  build() {
    Column() {
      // 应避免直接在Text组件内改变count的值
      Text(`${this.count++}`)
        .width(50)
        .height(50)
        .fontColor(this.col1)
        .onClick(() => {
          this.col2 = Color.Red;
        })
    }
  }
}

3、@Reuseable

@Reusable装饰的自定义组件具备可复用能力,结合懒加载等机制可以提高UI的性能。

@Reusable
@Component
struct MyComponent {
}

4、定义成员函数/变量

自定义组件除了必须要实现build()函数外,还可以实现其他成员函数,成员函数具有以下约束:

  • 自定义组件的成员函数为私有的,且不建议声明成静态函数。
  • 自定义组件可以包含成员变量,成员变量具有以下约束:

自定义组件的成员变量为私有的,且不建议声明成静态变量。

  • 自定义组件的成员变量本地初始化有些是可选的,有些是必选的。具体是否需要本地初始化,是否需要从- 父组件通过参数传递初始化子组件的成员变量,请参考状态管理。
@Entry
@Component
struct Parent {
  @State cnt: number = 0
  submit: () => void = () => {
    this.cnt++;
  }

  build() {
    Column() {
      Text(`${this.cnt}`)
      Son({ submitArrow: this.submit })
    }
  }
}

@Component
struct Son {
  submitArrow?: () => void
  build() {
    Row() {
      Button('add')
        .width(80)
        .onClick(() => {
          if (this.submitArrow) {
            this.submitArrow()
          }
        })
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .height(56)
  }
}

二、自定义组件的使用

组件可以在其他自定义组件中的build()函数中多次创建,实现自定义组件的重用,自定义组件的构造函数也可以支持有参数的实现。

@Entry
@Component
struct Parent {
  @State cnt: number = 0
  build() {
    Column() {
      Text(`${this.cnt}`)
      Son({ name:"crazymo" })
    }
  }
}

@Component
struct Son {
	private name: string;
	Son(str: string){
		this.name= str;
	}
  build() {
    Row() {
      Button('add')
        .width(80)
        })
    }
  }
}

如果在另外的文件中引用该自定义组件,需要使用export关键字导出,并在使用的页面import该自定义组件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1921775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

本地服务器部署外网可访问地址

一、开放服务器端口 &#xff08;1&#xff09;打开【控制面板】-【系统和安全】-【防火墙】-【高级设置】 &#xff08;2&#xff09;右键【新建规则】-【端口】-【程序&#xff1a;所有程序】-【操作&#xff1a;允许连接】-【配置文件&#xff1a;默认】-【名称&#xff1a;…

Customize-A-Video:文生视频自由定制

视频领域&#xff0c;尤其是文本到视频&#xff08;T2V&#xff09;扩散模型中的动作定制&#xff0c;尚未得到充分研究。来自马里兰大学、Adobe Research 和延世大学的研究团队提出了一种名为“Customize-A-Video”的新方法&#xff0c;本方法通过单一参考视频对动作进行建模&…

20240713 每日AI必读资讯

&#x1f697; 烧钱抢老司机饭碗&#xff1f;“萝卜快跑”事件辟谣 - 武汉相关负责人辟谣&#xff1a;无人车不是1000辆&#xff0c;只有400多辆 - “萝卜快跑”自动驾驶车可以通过单车智能、多重安全系统冗余保障以及5G云代驾平行驾驶三重冗余保障&#xff0c;确保自动驾驶…

vue学习day07-scoped样式冲突、data是一个函数、props详解、组件通信、非父子通信-event bus 事件总线

19、scoped样式冲突 &#xff08;1&#xff09;默认情况&#xff1a;写在组件中的样式会全局生效&#xff0c;因此会很容易造成多个组件之间的样式冲突问题。 1&#xff09;全局样式&#xff1a;默认组件中的样式会作用到全局 比如&#xff1a; 当只有box1设置边框时&#…

外贸国际短信群发工具的开发源代码!

在外贸行业中&#xff0c;快速、准确地与客户进行沟通是业务成功的关键之一&#xff0c;随着科技的不断进步&#xff0c;国际短信群发工具成为了外贸从业者不可或缺的工具。 本文将通过科普五段源代码&#xff0c;带您深入了解外贸国际短信群发工具的开发原理和实现过程。 一…

【题目/训练】回溯算法练习

&#x1f342;八皇后 二进制来表示。 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <unordered_map> using namespace std;int n; #define MASK(n) ((1<<(n1))-2) //如 6 得到的是1000 0000 …

阐述 C 语言中的参数传递机制

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&#xff0c;看过的人都说好。 文章目…

谷粒商城踩坑记录-网关服务启动报错

文章目录 一&#xff0c;错误表现二&#xff0c;错误原因三&#xff0c;解决方案1&#xff0c;排除无关依赖2&#xff0c;调整依赖关系 一&#xff0c;错误表现 在启动Spring Cloud Gateway服务时&#xff0c;控制台输出了一系列错误信息&#xff0c;指出应用程序未能成功启动…

单元测试Mockito笔记

文章目录 单元测试Mockito1. 入门1.1 什么是Mockito1.2 优势1.3 原理 2. 使用2.0 环境准备2.1 Mock1) Mock对象创建2) 配置Mock对象的行为(打桩)3) 验证方法调用4) 参数匹配5) 静态方法 2.2 常用注解1) Mock2) BeforeEach 与 BeforeAfter3) InjectMocks4) Spy5) Captor6) RunWi…

在 Java 中:为什么不能在 static 环境中访问非 static 变量?

在 Java 中&#xff1a;为什么不能在 static 环境中访问非 static 变量&#xff1f; 1、静态&#xff08;static&#xff09;变量2、非静态&#xff08;非static&#xff09;变量3、为什么不能访问&#xff1f;4、如何访问&#xff1f;5、总结 &#x1f496;The Begin&#x1f…

百度2025校园招聘内推开始啦

百度2025校园招聘内推开始啦&#xff0c;快来投递你心仪的职位吧&#xff08; 网申链接地址&#xff1a;https://talent.baidu.com/jobs/list?recommendCodeIZB4S3&recruitTypeGRADUATE &#xff09;填入内推码&#xff0c;完成投递&#xff0c;get内推绿色通道~我的内推码…

GEO的表达矩阵的探针ID转换成基因名称教程

GEO的表达矩阵的探针ID转换成基因名称教程 前情回顾 根据GSE id自动下载处理GEO数据(必须要运行的模块) 该模块的运行窗口截图 该模块的教程 知乎地址&#xff1a;根据GEO的GSE数据集编号自动下载和处理GEO数据教程: https://zhuanlan.zhihu.com/p/708053447 该根据GSE id…

第1章 初识 Express

1.1 什么是 Express Express 是一个简洁而灵活的 Node.js Web 应用框架&#xff0c;提供了一系列强大的特性用于开发 Web 和移动应用。它基于 Node.js 构建&#xff0c;并且与 Node.js 的非阻塞 I/O 模型无缝集成&#xff0c;使其非常适合于构建高性能的 Web 应用。 主要特点…

idea修改全局配置、idea中用aliyun的脚手架,解决配置文件中文乱码

idea修改全局配置 idea中用aliyun的脚手架&#xff0c;创建springBoot项目 解决配置文件中文乱码

【笔记】虚拟机中的主从数据库连接实体数据库成功后的从数据库不同步问题解决方法2

错误&#xff1a; Last_Errno: 1008 Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction ANONYMOUS at source log mysql-bin.000014, end_log_pos 200275. See error lo…

JavaWeb(四:Ajax与Json)

一、Ajax 1.定义 Ajax&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff1a;异步的 JavaScript 和 XML AJAX 不是新的编程语言&#xff0c;指的是⼀种交互方式&#xff1a;异步加载。 客户端和服务器的数据交互更新在局部页面的技术&#xff0c;不需要刷新…

剪画小程序:职场上如何提高工作效率?

亲爱的宝子们&#xff0c;不知道你们有没有遇到过这样的情况&#xff1a; 在公司里&#xff0c;老板突然让你整理一份国外产品介绍视频里的关键信息&#xff0c;可那是外语的&#xff0c;听得你一头雾水。 这时候&#xff0c;有什么方法或办法&#xff01;能快速准确地将视频中…

02对话系统---图片的导入

样式 例&#xff1a; 1.<styleH1> Hellow <styleH1>world 效果&#xff1a; 样式表 路径&#xff1a; 插入图片 插入默认图片 2.<sprite0> text<sprite0> 效果&#xff1a; 图集路径&#xff1a; 导入单个图片 给…

飞腾平台虚拟机组播性能调优指南

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

网优学习干货:xx5G速率优化现场实战版

速率概述 无线网络仍然是5G网络能力最容易受限的环节&#xff0c;无线网络技术的应用将最终决定5G网络能力的木桶深度。移动通信中传统关键技术在5G将会继续使用。5G NR在继承了LTE原有部分技术基础上&#xff0c;采用了一些技术演进和新技术创新。比如NR继承了LTE的OFDM和SC-…