今天我们学习【创建自定义组件】的部分
文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-create-custom-components-V5
创建自定义组件:
首先什么是自定义组件?
在我看来,是根据(开发者)的设计和功能需求,所创建的基本组件集合
(类似给你乐高的基础零部件,你DIY出自己的城市)
-----------------------------------------------------------------------------------------------------------------------------
以下是文档中的表述:
鸿蒙组件分类:
自定义组件的基本用法
index.ets中代码分为三个部分:
1.HelloComponent 自定义组件
@Component
struct HelloComponent {
@State message: string = 'Hello, 虾米!';
build() {
// HelloComponent自定义组件组合系统组件Row和Text
Row() {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.onClick(() => {
// 状态变量message的改变驱动UI刷新,UI从'Hello, 虾米!'刷新为'Hello, ArkUI!'
this.message = 'Hello, ArkUI!';
})
}
.height('100%')
.width('100%') //高和宽适应整个屏幕
.justifyContent(FlexAlign.Center)//垂直居中函数
}
}
2.HelloComponentParam 类:
class HelloComponentParam {
message: string = ""
}
3.ParentComponent 父组件 (应用入口)
@Entry //入口标志
@Component
struct ParentComponent {
param: HelloComponentParam = {
message: 'Hello, 虾米!'
}
build() {
Column() {
HelloComponent(this.param);
Divider()
HelloComponent(this.param);
}
.width('100%')
.height('100%') // 使Column高度和宽度占满整个屏幕
.backgroundColor(Color.Pink)
}
}
点击右上角【刷新】图标之后,预览效果:
自定义组件的基本结构 :
@Component (表示装饰器):仅能装饰struct关键字声明的数据结构。如图
@Component
struct SelfComponent {
}
build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。
@Component
struct SelfComponent {
build() {
}
}
@Entry:@Entry装饰的自定义组件将作为UI页面的入口。
@Entry
@Component
struct SelfComponent {
build(){}
}
@Reusable:@Reusable装饰的自定义组件具备可复用能力
(既当一个自定义组件被 @Reusable
装饰器标记时,这意味着该组件被设计为可以在应用程序中多次使用,而不需要每次都重新定义或实例化。)
@Reusable
@Component
struct SelfComponent {
}
命名路由跳转选项:
什么是路由?
在应用程序中,路由是用来决定不同URL应该显示什么内容的机制。比如,在网页应用或移动应用中,当你点击一个链接或者按钮,路由会告诉应用应该加载哪个页面。
什么是命名路由?
命名路由是一种特殊的路由方式,它给每个页面或路由分配一个名字,而不是直接使用URL路径。这样,当你想要从一个页面跳转到另一个页面时,你只需要告诉应用“我要去那个叫做‘home’的页面”,而不需要知道具体的URL路径。
命名路由的好处:
易于理解和记忆:使用名字比记住复杂的URL路径更容易。
易于维护:如果URL路径需要更改,你只需要在一个地方更新它,而不是在整个应用中搜索和替换所有硬编码的路径。
代码清晰:使得代码更加清晰,因为你可以看到页面之间的导航关系。
结合语境理解表格
routeName (名称):
假设我们有一个用户资料页面,我们给它一个routeName
为'userProfile'
。在代码中,我们可以通过这个名字来引用这个页面,而不是使用具体的路径。
storage (存储):
对于用户资料页面,我们可能希望在用户离开后再次回来时,页面能够恢复到之前的状态。我们可以使用storage
选项来指定一个LocalStorage
对象,用于保存和读取页面状态。
useSharedStorage12+ (是否使用共享存储):
如果我们的应用中有多个页面需要共享某些数据(例如用户信息),我们可以设置useSharedStorage12+
为true
。这样,这些页面将使用通过LocalStorage.getShared()
获取的共享LocalStorage
实例,从而能够共享数据。
成员函数/变量
自定义组件的参数规定
build()函数:
@Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
@Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。
@Entry
@Component
struct MyComponent {
build() {
// 根节点唯一且必要,必须为容器组件
Row() {
ChildComponent()
}
}
}
@Component
struct ChildComponent {
build() {
// 根节点唯一且必要,可为非容器组件
Image('test.jpg')
}
}
build() {
// 反例:不允许声明本地变量
let a: number = 1;
}
build() {
// 反例:不允许console.info
console.info('print debug log');
}
build() {
// 反例:不允许本地作用域
{
...
}
}
@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())
}
}
}
build() {
Column() {
// 反例:不允许使用switch语法
switch (expression) {
case 1:
Text('...')
break;
case 2:
Image('...')
break;
default:
Text('...')
break;
}
// 正例:使用if
if(expression == 1) {
Text('...')
} else if(expression == 2) {
Image('...')
} else {
Text('...')
}
}
}
build() {
Column() {
// 反例:不允许使用表达式
(this.aVar > 10) ? Text('...') : Image('...')
}
}
@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;
})
Button("change col1").onClick(() =>{
this.col1 = Color.Pink;
})
}
.backgroundColor(this.col2)
}
}
自定义组件通用样式
自定义组件通过“.”链式调用的形式设置通用样式。(注释部分都是通过.调用的)附带运行结果
@Component
struct MyComponent2 {
build() {
Row(){
Button(`Pink World`)
.backgroundColor('#c9e30dfb') //按钮背景色
.fontSize(40) //按钮字体大小
}
.justifyContent(FlexAlign.Center) //ROW居中显示
.width('100%')
.height('100%') //ROE宽高100%适应屏幕
}
}
@Entry
@Component
struct MyComponent {
build() {
Row() {
MyComponent2()
.width('100%')
.height('100%') //ROE宽高100%适应屏幕
.backgroundColor(Color.Pink) //ROW背景色
}
}
}