鸿蒙组件

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表达式的一个重要特性是它不绑定自己的thisargumentssuper,或者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!');
        })
    }
}

 

posted @   多见多闻  阅读(86)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2023-06-26 Unity计算表面积
点击右上角即可分享
微信分享提示