2024-09-09

HarmonyOS Next应用开发:UI范式介绍

ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。下面我们以一个具体的示例来说明UI范式的基本语法。如下图所示,当点击按钮时,文本内容从“Hello ,World”变为“你好,鸿蒙”。


基本组成

ArkTS的基本组成如下所示:



此示例我们定义了一个入口组件Index,并且该组件为自定义组件,定义了一个该组件的状态变量message,该状态变量的变化会触发UI的刷新。Index自定义组件组合了系统组件Row、Column、Text、Button,并通过“.”链式调用的形式设置通用样式。Button通过链式调用设置onClick()事件方法,通过触发组件的事件方法改变状态数据,UI从'Hello,World'刷新为'你好,鸿蒙'。

装饰器:

用于装饰类、结构、方法以及变量,并赋予其特殊的含义。
@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。
@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。
@State表示组件中的状态变量,状态变量变化会触发UI刷新。

UI描述:

以声明式的方式来描述UI的结构,build()函数用于定义自定义组件的声明式UI描述。
@Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
@Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。

@Entry
@Component
struct MyComponent {
  build() {
    // 根节点唯一且必要,必须为容器组件
    Row() {
      ChildComponent()
    }
  }
}

@Component
struct ChildComponent {
  build() {
    // 根节点唯一且必要,可为非容器组件
    Image($r('app.media.icon'))
      .width(50)
      .height(50)
  }
}

build()中不允许声明本地变量;不允许直接使用console.info,但允许在方法或者函数里使用;不允许创建本地的作用域:

build() {
    // 不允许声明本地变量
    let a: number = 1;
    // 不允许console.info
    console.info('print debug log');
    // 不允许本地作用域
    {
      
    }
}

不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值;不允许使用switch语法,如果需要使用条件判断,请使用if;不允许使用表达式:

@Component
struct ParentComponent {
  no:number = 0

  doSomeCalculations() {
  }

  calcTextValue(): string {
    return 'Hello World';
  }

  @Builder doSomeRender() {
    Text(`Hello World`)
  }

  build() {
    Column() {
      // 反例:不能调用没有用@Builder装饰的方法
      this.doSomeCalculations();
      // 正例:可以调用
      this.doSomeRender();
      // 正例:参数可以为调用TS方法的返回值
      Text(this.calcTextValue())

      // 反例:不允许使用switch语法
      switch (this.no) {
        case 0:
          Text('0')
          break;
        case 1:
          Text('1')
          break;
        default:
          Text('2')
          break;
      }
      // 正例:使用if
      if(this.no == 0) {
        Text('0')
      } else if(this.no == 1) {
        Text('1')
      } else {
        Text('2')
      }

      // 反例:不允许使用表达式
      (this.no > 10) ? Text('100') : Text('0')
    }
  }
}

不允许直接改变状态变量:

@Component
struct MyComponent {
  @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)
  }
}
自定义组件:

可复用的UI单元,可组合其他组件,基于struct实现,struct + 自定义组件名 + {...}且被@Component装饰的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。自定义组件必须定义build()函数。

系统组件:

框架中默认内置的基础和容器组件,可直接被开发者调用,比如示例中的Column、Text、Button。

属性方法:

组件可以通过链式调用配置多项属性,如fontSize()、width()、height()、backgroundColor()等。

事件方法:

组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容