鸿蒙组件
ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。
一、创建组件
根据组件构造方法的不同,创建组件包含有参数和无参数两种方式。
说明,创建组件时不需要new运算符。
1.无参数
如果组件的接口定义没有包含必选构造参数,则组件后面的“()”不需要配置任何内容。例如,Divider组件不包含构造参数:
Column() {
Text('item 1')
Divider()
Text('item 2')
}
2.有参数
如果组件的接口定义包含构造参数,则在组件后面的“()”配置相应参数。
Image组件的必选参数src。
Image('https://xyz/test.jpg')
Text组件的非必选参数content。
// string类型的参数
Text('test')
// $r形式引入应用资源,可应用于多语言场景
Text($r('app.string.title_value'))
// 无参数形式
Text()
这里的$r
是一个资源引用函数,它接受一个字符串参数,这个参数是资源的ID。在这个例子中,app.string.title_value
是一个资源ID,它指向了应用资源中的某个字符串值。
在多语言支持方面,鸿蒙操作系统会根据用户的语言偏好选择合适的资源文件。假设你有两个资源文件,分别是zh-CN
(简体中文)和en-US
(英语),那么当用户的设备设置为简体中文时,$r('app.string.title_value')
会自动引用zh-CN
资源文件中的title_value
字符串;如果设备设置为英语,则会引用en-US
资源文件中的对应字符串。
这种方式使得应用能够轻松支持多语言,开发者不需要编写额外的逻辑来处理不同语言的资源文件,只需在资源目录中提供相应的本地化资源,并在代码中使用$r
来引用它们。
变量或表达式也可以用于参数赋值,其中表达式返回的结果类型必须满足参数类型要求。
例如,设置变量或表达式来构造Image和Text组件的参数。
Image(this.imagePath)
Image('https://' + this.imageUrl)
Text(`count: ${this.count}`)
二、配置属性
属性方法以“.”链式调用的方式配置系统组件的样式和其他属性,建议每个属性方法单独写一行。
配置Text组件的字体大小。
Text('test')
.fontSize(12)
//配置组件的多个属性。
Image('test.jpg')
.alt('error.jpg')
.width(100)
.height(100)
除了直接传递常量参数外,还可以传递变量或表达式。
Text('hello')
.fontSize(this.size)
Image('test.jpg')
.width(this.count % 2 === 0 ? 100 : 200)
.height(this.offset + 100)
这里的Image
构造函数接受一个字符串参数,这个参数通常是图片资源的路径。在这个例子中,它将尝试加载名为test.jpg
的图片文件。
接下来,.width()
和.height()
方法用于设置Image组件的宽度和高度。这两个方法可以接受不同的参数类型,包括数字(表示像素值)、百分比(表示相对于父容器的比例)或其他表达式。
在.width()
方法中,使用了条件(三元)运算符this.count % 2 === 0 ? 100 : 200
来动态设置宽度。这里的意思是:如果this.count
是偶数(this.count % 2 === 0
),则宽度设置为100像素;如果是奇数,则宽度设置为200像素。
在.height()
方法中,高度被设置为this.offset + 100
。这里的this.offset
可能是组件中的一个属性,它表示一个偏移量。因此,图片的高度将是this.offset
的值加上100像素。
综上所述,这段代码的作用是创建一个Image组件,加载名为test.jpg
的图片,并根据this.count
的值决定图片的宽度(100像素或200像素),以及根据this.offset
的值加上100像素来决定图片的高度。这种动态设置属性的方式使得组件可以响应状态变化,从而实现更丰富的交互效果。
在JavaScript(包括TypeScript,因为TypeScript是JavaScript的超集)中,==
和===
是两种不同的比较操作符,它们用于比较两个值是否相等,但是它们在比较的方式上有所不同。
==
(等于操作符):它会比较两个操作数的值,如果这两个值的类型不同,那么JavaScript引擎会尝试将它们转换为相同的类型,然后再进行比较。这种转换被称为类型强制转换(type coercion)。例如,数字和字符串形式的数字可以被认为是相等的。
0 == '0'; // true,因为字符串'0'会被转换成数字0
===
(严格等于操作符):它会比较两个操作数的值和类型,如果两者都相同,则返回true
。如果类型不同,即使值在类型转换后相同,也会返回false
。===
不会进行类型强制转换。
0 === '0'; // false,因为数字0和字符串'0'的类型不同
总结一下,===
通常被认为是更安全和更可预测的比较方式,因为它避免了不必要的类型转换,从而减少了错误的发生。因此,在大多数情况下,推荐使用===
而不是==
,除非你明确需要类型转换的比较。
对于系统组件,ArkUI还为其属性预定义了一些枚举类型供开发者调用,枚举类型可以作为参数传递,但必须满足参数类型要求。
例如,可以按以下方式配置Text组件的颜色和字体样式。
Text('hello')
.fontSize(20)
.fontColor(Color.Red)
.fontWeight(FontWeight.Bold)
三、配置事件
事件方法以“.”链式调用的方式配置系统组件支持的事件,建议每个事件方法单独写一行。
使用lambda表达式配置组件的事件方法。
Button('Click me')
.onClick(() => {
this.myText = 'ArkUI';
})
Lambda表达式,也称为箭头函数,是JavaScript (ES6+) 和 TypeScript 中的一种语法糖,用于编写匿名函数。Lambda表达式提供了一种更简洁的方式来书写函数,特别是在单行函数或者嵌入其他表达式中的函数。
Lambda表达式的基本语法如下:
参数 => { 函数体 }
或者,如果只有一个参数并且函数体只有一条语句,可以省略参数周围的括号和函数体的大括号:
参数 => 表达式
在例子中:
() => { this.myText = 'ArkUI'; }
这是一个没有参数的Lambda表达式。它被用作Button组件的onClick
事件处理函数。当按钮被点击时,这个Lambda表达式会被调用,并且执行其中的代码。在这个例子中,Lambda表达式的函数体是:
{ this.myText = 'ArkUI'; }
这行代码的作用是将当前对象的myText
属性设置为字符串'ArkUI'
。
Lambda表达式的一个重要特性是它不绑定自己的this
,arguments
,super
,或者new.target
。这意味着在Lambda表达式中,this
的值与外部上下文中的this
相同。在您的例子中,this
指向包含这个Lambda表达式的对象,即Button组件的实例。因此,this.myText = 'ArkUI';
实际上是在修改该组件实例的myText
属性。
使用匿名函数表达式配置组件的事件方法,要求使用bind,以确保函数体中的this指向当前组件。
Button('add counter')
.onClick(function(){
this.counter += 2;
}.bind(this))
在JavaScript中,函数的bind()
方法用于创建一个新的函数,这个新函数的this
关键字被绑定到传入bind()
方法的第一个参数。在您提供的例子中,bind(this)
用于确保在onClick
事件处理函数中,this
指向的是当前组件的上下文,而不是按钮本身或其他对象。
Button('add counter')
创建了一个按钮组件,其文本显示为 “add counter”。.onClick()
方法用于为按钮组件注册一个点击事件的处理函数。function(){ this.counter += 2; }
是一个匿名函数,当按钮被点击时,这个函数将被调用。在这个函数中,this.counter += 2;
试图将当前上下文中的counter
属性增加2。.bind(this)
是调用这个匿名函数的bind
方法,并将当前组件的上下文(this
)作为参数传递给bind
。这样,即使这个匿名函数在全局或不同的上下文中被调用,this
仍然会指向原始的组件上下文。
在JavaScript中,每个函数都有它自己的this
值,通常取决于函数是如何被调用的。在事件处理函数中,this
通常指向触发事件的元素(在这个例子中是按钮)。但是,如果我们想在事件处理函数中使用当前组件的上下文,我们需要使用bind(this)
来确保this
的正确性。
在ES6及以后的版本中,通常推荐使用箭头函数(Lambda表达式)来代替bind(this)
,因为箭头函数不绑定自己的this
,它们会捕获包围它们的上下文中的this
值。因此,上面的代码可以使用箭头函数简化为:
Button('add counter')
.onClick(() => {
this.counter += 2;
})
在这个简化版本中,箭头函数中的this
自动指向包围它的上下文中的this
,即组件的上下文,所以我们不需要使用bind(this)
。
使用组件的成员函数配置组件的事件方法。
myClickHandler(): void {
this.counter += 2;
}
....
Button('add counter')
.onClick(this.myClickHandler.bind(this))
四、配置子组件
如果组件支持子组件配置,则需在尾随闭包"{...}"中为组件添加子组件的UI描述。Column、Row、Stack、Grid、List等组件都是容器组件。
以下是简单的Column组件配置子组件的示例。
Column() {
Text('Hello')
.fontSize(100)
Divider()
Text(this.myText)
.fontSize(100)
.fontColor(Color.Red)
}
容器组件均支持子组件配置,可以实现相对复杂的多级嵌套。
Column() {
Row() {
Image('test1.jpg')
.width(100)
.height(100)
Button('click +1')
.onClick(() => {
console.info('+1 clicked!');
})
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2023-06-26 Unity计算表面积