【零基础学鸿蒙】ArkTS开发语言介绍

在之前的教学中,我们学习了下载安装DevEco Studio等相关知识。今天开始讲ArkTS

1.1 TypeScrip快速入门

学习TypeScript对于HarmonyOS应用开发至关重要。在HarmonyOS中,主力编程语言为ArKTS,它是基于TypeScript的一种语言,其通过与ArkUI框架的匹配,拓展了声明式UI和状态管理等能力,使开发者能够以更简洁自然的方式开发跨端应用。TypeScript本身是JavaScript的超集,通过引入静态类型定义等特性,提高了代码的可维护性和可读性,有助于在编码阶段检测潜在错误,提高开发效率另外,学习TypeScript还为处理HarmonyOS应用中的UI和应用状态提供了更强大的支持,在并发任务方面也有相应的扩展。为了更好地对HarmonyOS进行开发需要掌握TypeScript语言,本接我们重点介绍TypeScript语言。
鸿蒙学习小助手V【hmos19】解答、咨询、项目实战

1.1.1 编程语言介绍

ArkTS是HarmonyOS优选的主力应用开发语言。它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。要了解什么是ArkTS,我们首先要了解下ArkTS、TypeScript和JavaScript之间的关系:

图片

lJavaScript是一种属于网络的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。

lTypeScript 是 JavaScript 的一个超集,它扩展了 JavaScript 的语法,通过在JavaScript的基础上添加静态类型定义构建而成,是一个开源的编程语言。

lArkTS兼容TypeScript语言,拓展了声明式UI、状态管理、并发任务等能力。

在学习ArkTS声明式的相关语法之前,我们首先学习下TypeScript的基础语法。

1.1.2 基础类型

TypeScript支持一些基础的数据类型,如布尔型、数组、字符串等,下文举例几个较为常用的数据类型,我们来了解下他们的基本使用。

Ø布尔值

TypeScript中可以使用boolean来表示这个变量是布尔值,可以赋值为true或者false。例如我们这里可以设置IsDone为False来表示未完成。

let isDone: boolean = false;

Ø数字

TypeScript里的所有数字都是浮点数,这些浮点数的类型是 number。除了支持十进制,还支持二进制、八进制、十六进制。如下我们用十进制、二进制、八进制和十六进制分别定义了2023,当把数据通过日志方式打印出来,结果都会转换为十进制,也都是2023。

let decLiteral: number = 2023;

let binaryLiteral: number = 0b11111100111;

let octalLiteral: number = 0o3747;

let hexLiteral: number = 0x7e7;

Ø字符串

TypeScript里使用 string表示文本数据类型, 可以使用双引号( ")或单引号(')表示字符串。例如我们这里定义Name是一个字符串类型,其数值我们可以用双引号或者单引号包裹起来。

let name: string = "Jacky";

name = "Tom";

name = 'Mick';

Ø数组

TypeScrip有两种方式可以定义数组。第一种,可以在元素类型后面接上 [],表示由此类型元素组成的一个数组。

let list: number[] = [1, 2, 3];

第二种方式是使用数组泛型,Array<元素类型>。

let list: Array<number> = [1, 2, 3];

Ø元组

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。

例如这里我们定义了一个X元组,类型为String和Number。第一行的赋值和我们元组定义的顺序是一致的,这种是正确的。第二行先赋值Number后赋值String,这种赋值的顺序和我们定义的不一致,所以是错误的。

let x: [string, number];

x = ['hello', 10]; // OK

x = [10, 'hello']; // Error

Ø枚举

enum类型是对JavaScript标准数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字。例如我们这里定义Color为Red, Green和Blue,到时候就可以使用Color.Green来定义颜色。

enum Color {Red, Green, Blue};

let c: Color = Color.Green;

ØUnknown

有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。那么我们可以使用unknown类型来标记这些变量。

如下案例中,这里的Not Sure定义为Unknown后,我们可以赋值为Number类型,也可以赋值为String类型,还可以赋值为false类型。

let notSure: unknown = 4;

notSure = 'maybe a string instead';

notSure = false;

ØVoid

当一个函数没有返回值时,你通常会见到其返回值类型是 void。如下的test方法,其返回类型就是Void。

function test(): void {

   console.log('This is function is void');

}

ØNull 和 Undefined

TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。

let u: undefined = undefined;

let n: null = null;

Ø联合类型

联合类型(Union Types)表示取值可以为多种类型中的一种。例如我们这里定义MyFavoriteNumber为联合类型,其取值可以是String或者Number,我们可以给其赋值为字符串7,也可以给其赋值为Number类型7。联合类型在日常的使用过程中用的比较多,大家要掌握这种定义方式。

let myFavoriteNumber: string | number;

myFavoriteNumber = 'seven';

myFavoriteNumber = 7;

1.1.3 条件语句

条件语句用于基于不同的条件来执行不同的动作。TypeScript 条件语句是通过一条或多条语句的执行结果(True 或 False)来决定执行的代码块。

Øif 语句

TypeScript if 语句由一个布尔表达式后跟一个或多个语句组成。例如,如下代码中是一个If语句,定义的Number为5,判断的条件是Number大于0,程序满足这个条件会输出数字为正数。

var num:number = 5

if (num > 0) {

   console.log('数字是正数')

}

Øif…else 语句

一个 if 语句后可跟一个可选的 else 语句,else 语句在布尔表达式为 false 时执行。如下代码中声明一个If-else语句,定义的Number是12,符合Number对2取余等于0的条件,所以输出为偶数。

var num:number = 12;

if (num % 2==0) {

    console.log('偶数');

} else {

    console.log('奇数');

}

Øif…else if…else 语句

if…else if…else 语句在执行多个判断条件的时候很有用。如下代码中是一个If-else语句,定义的Number为0,满足最后的else条件,所以输出为0。

var num:number = 0

if(num > 0) {

    console.log(num+' 是正数')

} else if(num < 0) {

    console.log(num+' 是负数')

} else {

    console.log(num+' 为0')

}

Øswitch…case 语句

除了可以通过If-else语句进行条件判断外,还可以通过Switch-case语句进行条件判断。一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case,且被测试的变量会对每个 switch case 进行检查。

如下代码中我们有4个Case条件,分别是A输出日志优,B输出日志良,C输出日志及格,D输出日志不及格,最后还有一个default条件,当输入的字符不在ABCD中则表示非法输入,最后我们定义的Grade为A,所以这个代码打印的日志为优。

var grade:string = 'A';

switch(grade) {

    case 'A': {

        console.log('优');

        break;

    }

    case 'B': {

        console.log('良');

        break;

    }

    case 'C': {

        console.log('及格');

        break;    

    }

    case 'D': {

        console.log('不及格');

        break;

    }  

    default: {

        console.log('非法输入');

        break;              

    }

}

1.1.4 函数

函数是一组一起执行一个任务的语句,函数声明要告诉编译器函数的名称、返回类型和参数。TypeScript可以创建有名字的函数和匿名函数,其创建方法如下:

// 有名函数

function add(x, y) {

  return x + y;

}

 

// 匿名函数

let myAdd = function (x, y) {

  return x + y;

};

Ø为函数定义类型

为了确保输入输出的准确性,我们可以为上面那个函数添加类型:

// 有名函数:给变量设置为number类型

function add(x: number, y: number): number {

  return x + y;

}

 

// 匿名函数:给变量设置为number类型

let myAdd = function (x: number, y: number): number {

  return x + y;

};

以上函数的名称叫做Add,实现的是两个数值的累加,参数是X和Y两个number类型的数字,返回值是X+Y的结果。其返回的类型也是number类型,上面一个函数是有名函数,下面一个函数是匿名函数,匿名函数没有函数名,但其作用是一样的。

Ø可选参数

在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。比如,我们想让lastName是可选的。使用了可选参数后,我们在调用函数的时候就可以传入一个参数或者两个参数,如Result1和Result2中的代码所示:

function buildName(firstName: string, lastName?: string) {

    if (lastName)

        return firstName + ' ' + lastName;

    else

        return firstName;

}

 

let result1 = buildName('Bob');

let result2 = buildName('Bob', 'Adams');

Ø剩余参数

函数的入参除了可以使用可选参数外,还可以使用剩余参数。剩余参数会被当做个数不限的可选参数,可以一个都没有,同样也可以有任意个。 可以使用省略号( …)进行定义。如下代码中,我们调用getEmployeeName方法时,可以只传入firstName,也就是Joseph,不传入剩余参数,也可以传入多个剩余参数:Samuel,Lucas,MacKinzie等。

function getEmployeeName(firstName: string, ...restOfName: string[]) {

  return firstName + ' ' + restOfName.join(' ');

}

 

let employeeName = getEmployeeName('Joseph', 'Samuel', 'Lucas', 'MacKinzie');

Ø箭头函数

ES6版本的TypeScript提供了一个箭头函数,它是定义匿名函数的简写语法,用于函数表达式,它省略了function关键字。箭头函数的定义如下,其函数是一个语句块:

( [param1, parma2,…param n] )=> {

    // 代码块

}

其中,括号内是函数的入参,可以有0到多个参数,箭头后是函数的代码块。我们可以将这个箭头函数赋值给一个变量,如下所示:

let arrowFun = ( [param1, parma2,…param n] )=> {

    // 代码块

}

如何要主动调用这个箭头函数,可以按如下方法去调用:

arrowFun(param1, parma2,…param n)

接下来我们看看如何将我们熟悉的函数定义方式转换为箭头函数。我们可以定义一个判断正负数的函数,如下:

function testNumber(num: number) {

  if (num > 0) {

    console.log(num + ' 是正数');

  } else if (num < 0) {

    console.log(num + ' 是负数');

  } else {

    console.log(num + ' 为0');

  }

}

其调用方法如下:

testNumber(1) //输出日志:1 是正数

如果将这个函数定义为箭头函数,定义如下所示:

let testArrowFun = (num: number) => {

  if (num > 0) {

    console.log(num + ' 是正数');

  } else if (num < 0) {

    console.log(num + ' 是负数');

  } else {

    console.log(num + ' 为0');

  }

}

其调用方法如下:

testArrowFun(-1) //输出日志:-1 是负数

后面,我们在学习HarmonyOS应用开发时会经常用到箭头函数。例如,给一个按钮添加点击事件,其中onClick事件中的函数就是箭头函数。

Button("Click Now")

  .onClick(() => {

    console.info("Button is click")

  })

1.1.5 类

TypeScript支持基于类的面向对象的编程方式,定义类的关键字为 class,后面紧跟类名。类描述了所创建的对象共同的属性和方法。

Ø类的定义

例如,我们可以声明一个Person类,这个类有3个成员:一个是属性(包含name和age),一个是构造函数,一个是getPersonInfo方法,其定义如下所示。

class Person {

  private name: string

  private age: number

 

  constructor(name: string, age: number) {

    this.name = name;

    this.age = age;

  }

 

  public getPersonInfo(): string {

    return `My name is ${this.name} and age is ${this.age}`;

  }

}

通过上面的Person类,我们可以定义一个人物Jacky并获取他的基本信息,其定义如下,我们可以使用new方法,传入person的姓名和年龄,创建为person1对象,person1可以调用其中的公有属性的方法,也就是getpersoninfo方法,这个是一个最简单的类的定义和调用。当然类里面还有很多的知识,比如我们可以通过修改修饰符,private public等来控制属性和方法的访问权限,这些知识大家可以参考TS的相关文档进行自行学习。

let person1 = new Person('Jacky', 18);

person1.getPersonInfo();

Ø继承

继承就是子类继承父类的特征和行为,使得子类具有父类相同的行为。TypeScript中允许使用继承来扩展现有的类,对应的关键字为extends。如下案例中,我们定义employee是继承于person的employee叫person新增了一个属性department,我们可以这样去定义它的构造方法,通过super关键字实际上就调用了person中的构造方法,初始化name和age,并在构造方法中初始化好了department,employee有个公有方法,getemployeeinfo获取雇员的信息,其中调用getpersoninfo来获取雇员的姓名、年龄信息。

class Employee extends Person {

  private department: string

 

  constructor(name: string, age: number, department: string) {

    super(name, age);

    this.department = department;

  }

 

  public getEmployeeInfo(): string {

    return this.getPersonInfo() + ` and work in ${this.department}`;

  }

}

通过上面的Employee类,我们可以定义一个人物Tom,这里可以获取他的基本信息,也可以获取他的雇员信息,其定义如下:

let person2 = new Employee('Tom', 28, 'HuaWei');

person2.getPersonInfo();

person2.getEmployeeInfo();

在TypeScript中,有public、private、protected修饰符,其功能和具体使用场景大家可以参考TypeScript的相关学习资料,进行拓展学习。

1.1.6 模块

随着应用越来越大,通常要将代码拆分成多个文件,即所谓的模块(module)。模块可以相互加载,并可以使用特殊的指令 export 和 import 来交换功能,从另一个模块调用一个模块的函数。

两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。

Ø导出

任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加export关键字来导出,例如我们要把NewsData这个类导出,代码示意如下:

export class NewsData {

  title: string;

  content: string;

  imagesUrl: Array<NewsFile>;

  source: string;

 

  constructor(title: string, content: string, imagesUrl: Array<NewsFile>, source: string) {

    this.title = title;

    this.content = content;

    this.imagesUrl = imagesUrl;

    this.source = source;

  }

}

Ø导入

模块的导入操作与导出一样简单。 可以使用以下 import形式之一来导入其它模块中的导出内容。

import { NewsData } from '../common/bean/NewsData';

以上案例中,我们在一个文件中定义了一个类news data,我们要在其他文件中引用这个类,首先就需要在这个类的前面加一个修饰符export,之后我们可以利用import来导入这个类,这个类的具体路径是填写在form后面的。export进来后,我们就可以在这个模块中引用其他模块中定义的NewsData。

1.1.7 可迭代对象

当一个对象实现了Symbol.iterator属性时,我们认为它是可迭代的。一些内置的类型如Array,Map,Set,String,Int32Array,Uint32Array等都具有可迭代性。

Øfor…of 语句

for…of会遍历可迭代的对象,调用对象上的Symbol.iterator方法。下面是在数组上使用for…of的简单例子,如这里定了一个someArray 数组,使用for-of语句进行循环遍历,可以打印这个数组中的元素。

let someArray = [1, "string", false];

 

for (let entry of someArray) {

    console.log(entry); // 1, "string", false

}

Øfor…of vs. for…in 语句

for…of和for…in均可迭代一个列表,但是用于迭代的值却不同:for…in迭代的是对象的键,而for…of则迭代的是对象的值。如下,for…in打印的是数组的下标。

let list = [4, 5, 6];

 

for (let i in list) {

    console.log(i); // "0", "1", "2",

}

 

for (let i of list) {

    console.log(i); // "4", "5", "6"

}

1.1.8 DevEco Studio中配置TypeScript

配置node.js的环境变量:

图片

安装 typescript:

npm install -g typescript

安装完成后我们可以使用tsc 命令来执行 TypeScript 的相关代码,以下是查看版本号:

$ tsc -v

Version 5.3.2

1.1 初识ArkTs语言

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。因此,在学习ArkTS语言之前,建议开发者具备TS语言开发能力。

当前,ArkTS在TS的基础上主要扩展了如下能力:

l基本语法:ArkTS定义了声明式UI描述、自定义组件和动态扩展UI元素的能力,再配合ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共同构成了UI开发的主体。

l状态管理:ArkTS提供了多维度的状态管理机制。在UI开发框架中,与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,还可以在应用全局范围内传递或跨设备传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递。开发者可以灵活的利用这些能力来实现数据和UI的联动。

l渲染控制:ArkTS提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。数据懒加载从数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

未来,ArkTS会结合应用开发/运行的需求持续演进,逐步提供并行和并发能力增强、系统类型增强、分布式开发范式等更多特性。

1.2 ArkTS基本语法

1.2.1 基本语法概述

在初步了解了ArkTS语言之后,我们以一个具体的示例来说明ArkTS的基本组成。该案例中当开发者点击按钮时,文本内容从“Hello World”变为“Hello ArkUI”,创建步骤如下。

1)打开 DevEvo Studio开发工具,新建项目

项目创建完成,进入该项目等待项目初始化完成即可:

2)在Index.ets中写入如下代码

@Entry
@Component
struct Hello {
  @State myText: string = 'World'

  build() {
    Column(){
      Text(`Hello ${this.myText}`)
        .fontSize(50)
      Divider()
      Button('Click me')
        .onClick(()=>{
          this.myText='ArkUI'
        })
        .height(50)
        .width(100)
        .margin({top:20})
    }
  }
}

对以上代码详细解释如下:

//@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。
@Entry
/**
 * @Component是一种装饰器,代表自定义组件,用@Component 装饰的 struct Hello 代表一个自定义的结构体,名字是Hello,是可重用的UI单元,可以与其他组件组合。
 */
@Component
struct Hello {
  //@State 是一种装饰器,被它装饰的变量 myText 值发生改变时,会触发该变量所对应的自定义组件 Hello 的 UI 界面进行自动刷新。
  @State myText: string = 'World'

  //build 方法中的代码块表示UI描述,以声明式的方式描述UI结构。
  build() {
    //Column 是内置组件,表示设置一列
    Column(){
      //设置文本及内容
      Text(`Hello ${this.myText}`)
        .fontSize(50)//设置文本大小
      Divider() //Divider 提供分隔器组件,分隔不同内容块/内容元素。
      //设置按钮
      Button('Click me')
        //设置按钮点击事件,点击按钮时将 myText 由 World 改变成 ArkUI
        .onClick(()=>{
          this.myText='ArkUI'
        })
        .height(50) //设置按钮高度
        .width(100) //设置按钮宽度
        .margin({top:20}) //设置按钮外边距
    }
  }
}

3)打开预览,验证组件功能

当点击“Click me”按钮时,“Hello World”变换成“Hello ArkUI”。

在以上示例中,ArkTS的基本组成如下所示。

l装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新。

lUI描述:以声明式的方式来描述UI的结构,例如build()方法中的代码块。

l自定义组件:可复用的UI单元,可组合其他组件,如上述被@Component装饰的struct Hello。

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

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

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

系统组件、属性方法、事件方法具体使用可参考基于ArkTS的声明式开发范式。除此之外,ArkTS扩展了多种语法范式来使开发更加便捷:

l@Builder/@BuilderParam:特殊的封装UI描述的方法,细粒度的封装和复用UI描述。

l@Extend/@Style:扩展内置组件和封装属性样式,更灵活地组合内置组件。

lstateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。

1.2.2 声明式UI概述

ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。

1.2.2.1 创建组件

根据组件构造方法的不同,创建组件包含有参数和无参数两种方式。创建组件时不需要new运算符。

l无参数

如果组件的接口定义没有包含必选构造参数,则组件后面的“()”不需要配置任何内容。例如,Divider组件不包含构造参数:

Column() {

  Text('item 1')

  Divider()

  Text('item 2')

}

示例演示:

@Entry
@Component
struct UITest {
  build() {
    Column() {
      Text('item 1')
      Divider()
      Text('item 2')
    }
  }

预览如下:

l有参数

如果组件的接口定义包含构造参数,则在组件后面的“()”配置相应参数。

a.Image组件的必选参数src。

Image('https://xyz/test.jpg')

b.Text组件的非必选参数content。

// string类型的参数

Text('test')

// $r形式引入应用资源,可应用于多语言场景

Text($r('app.string.title_value'))

// 无参数形式

Text()

c.变量或表达式也可以用于参数赋值,其中表达式返回的结果类型必须满足参数类型要求。

Image(this.imagePath)

Image('https://' + this.imageUrl)

Text(`count: ${this.count}`)

示例演示:

@Entry
@Component
struct UITest {
  build() {
    Column() {
      Image('https://img0.baidu.com/it/u=110176915,621401482&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=665')
        .height(500)
      Text('美女')
    }
  }
}

预览如下:

1.2.2.2 配置属性

属性方法以“.”链式调用的方式配置系统组件的样式和其他属性,建议每个属性方法单独写一行。

l配置Text组件的字体大小。

Text('test')

  .fontSize(12)

l配置组件的多个属性。

Image('test.jpg')

  .alt('error.jpg')    

  .width(100)    

  .height(100)

l除了直接传递常量参数外,还可以传递变量或表达式。

Text('hello')

  .fontSize(this.size)

Image('test.jpg')

  .width(this.count % 2 === 0 ? 100 : 200)    

  .height(this.offset + 100)

l对于系统组件,ArkUI还为其属性预定义了一些枚举类型供开发者调用,枚举类型可以作为参数传递,但必须满足参数类型要求。

例如,可以按以下方式配置Text组件的颜色和字体样式。

Text('hello')

  .fontSize(20)

  .fontColor(Color.Red)

  .fontWeight(FontWeight.Bold)

示例:

@Entry
@Component
struct UITest {
  textSize: number = 50;
  count:number = 2;
  imageOffset:number = 700;

  build() {
    Column(){
      Text("Hello ArkTS")
        .fontSize(this.textSize)
        .fontColor(Color.Red)
        .fontWeight(FontWeight.Bold)

      Image('https://img0.baidu.com/it/u=110176915,621401482&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=665')
        .width(this.count%2 === 0?500:200)
        .height(this.imageOffset + 100)
    }

  }
}

预览如下:

鸿蒙学习小助手V【hmos19】解答、咨询、项目实战

1.2.2.3 配置事件

事件方法以“.”链式调用的方式配置系统组件支持的事件,建议每个事件方法单独写一行。

l使用箭头函数配置组件的事件方法。

Button('Click me')

  .onClick(() => {

    this.myText = 'ArkUI';

  })

l使用匿名函数表达式配置组件的事件方法,要求使用bind,以确保函数体中的this指向当前组件。

Button('add counter')

  .onClick(function(){

    this.counter += 2;

  }.bind(this))

l使用组件的成员函数配置组件的事件方法。

myClickHandler(): void {

  this.counter += 2;

}

...

Button('add counter')

  .onClick(this.myClickHandler.bind(this))

示例:

@Entry
@Component
struct UITest {
  @State textSize: number = 20;

  myClickHandler(): void {
    this.textSize += 10;
  }

  build() {
    Column() {
      Text("Hello ArkTS")
        .fontSize(this.textSize)
        .fontColor(Color.Red)
        .fontWeight(FontWeight.Bold)
      Divider()
      Button("增大字体")
        .height(50)
        .width(100)
        .margin(20)
        .onClick(this.myClickHandler.bind(this))
    }
  }
}

预览如下,每次点击“增大字体”按钮后,“Hello ArkTS”都会变大。

1.2.2.4 配置子组件

如果组件支持子组件配置,则需在尾随闭包"{…}"中为组件添加子组件的UI描述。Column、Row、Stack、Grid、List等组件都是容器组件。

l以下是简单的Column组件配置子组件的示例。

Column() {

Text(‘Hello’)

.fontSize(100)

Divider()

Text(this.myText)

.fontSize(100)

.fontColor(Color.Red)

}

l容器组件均支持子组件配置,可以实现相对复杂的多级嵌套。

Column() {

Text(‘Hello’)

.fontSize(100)

Divider()

Text(this.myText)

.fontSize(100)

.fontColor(Color.Red)

}

1.2.3 基础组件-Text

Text组件是可以显示一段文本的组件。该组件从API Version 7开始支持,从API version 9开始,该接口支持在ArkTS卡片中使用。

1.2.3.1 用法
该组件使用方式如下:

Text(content?: string | Resource)

以上参数解释如下:

在这里插入图片描述
Text组件支持很多通用属性,如:width、height等,还支持如下属性:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
鸿蒙学习小助手V【hmos19】解答、咨询、项目实战在这里插入图片描述

1.2.3.2 示例

以下代码定义了一个名为 TextExample1 的组件,用于展示不同文本样式的效果,包括文本对齐、文本溢出处理和行高设置。

@Entry  // 使用 @Entry 装饰器标识这是一个入口组件。
@Component  // 使用 @Component 装饰器定义一个新组件。
struct TextExample1 {  // 定义名为 TextExample1 的结构体,代表这个组件。

  build() {  // 定义 build 方法来构建UI。
    Flex({  // 创建一个弹性布局容器。
      direction: FlexDirection.Column,  // 设置布局方向为垂直列。
      alignItems: ItemAlign.Start,  // 设置子项沿主轴的起始位置对齐。
      justifyContent: FlexAlign.SpaceBetween  // 设置子项间距均匀分布。
    }) {
      // 文本水平方向对齐方式设置
      // 单行文本
      Text('textAlign').fontSize(9).fontColor(0xCCCCCC)  // 创建一个文本组件,说明接下来的文本对齐设置。

      Text('TextAlign set to Center.')  // 创建一个文本组件,文本居中对齐。
        .textAlign(TextAlign.Center)  // 设置文本对齐方式为居中。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      Text('TextAlign set to Start.')  // 创建一个文本组件,文本起始对齐。
        .textAlign(TextAlign.Start)  // 设置文本对齐方式为起始对齐。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      Text('TextAlign set to End.')  // 创建一个文本组件,文本结束对齐。
        .textAlign(TextAlign.End)  // 设置文本对齐方式为结束对齐。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      // 多行文本
      Text('This is the text content with textAlign set to Center.')  // 创建一个多行文本组件,文本居中对齐。
        .textAlign(TextAlign.Center)  // 设置文本对齐方式为居中。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      Text('This is the text content with textAlign set to Start.')  // 创建一个多行文本组件,文本起始对齐。
        .textAlign(TextAlign.Start)  // 设置文本对齐方式为起始对齐。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      Text('This is the text content with textAlign set to End.')  // 创建一个多行文本组件,文本结束对齐。
        .textAlign(TextAlign.End)  // 设置文本对齐方式为结束对齐。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .width('100%')  // 设置宽度为100%。

      // 文本超长时显示方式
      Text('TextOverflow+maxLines').fontSize(9).fontColor(0xCCCCCC)  // 创建一个文本组件,说明接下来的文本溢出设置。

      // 超出maxLines截断内容展示
      Text('This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content. This is the setting of textOverflow to Clip text content This is the setting of textOverflow to None text content.')
        .textOverflow({ overflow: TextOverflow.Clip })  // 设置文本溢出方式为剪裁(Clip)。
        .maxLines(1)  // 设置最大行数为1。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。

      // 超出maxLines展示省略号
      Text('This is set textOverflow to Ellipsis text content This is set textOverflow to Ellipsis text content.'.split('')
        .join('\u200B'))
        .textOverflow({ overflow: TextOverflow.Ellipsis })  // 设置文本溢出方式为省略号(Ellipsis)。
        .maxLines(1)  // 设置最大行数为1。
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。

      Text('lineHeight').fontSize(9).fontColor(0xCCCCCC)  // 创建一个文本组件,说明接下来的行高设置。

      // 设置文本的行高
      Text('This is the text with the line height set. This is the text with the line height set.')
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
      Text('This is the text with the line height set. This is the text with the line height set.')
        .fontSize(12)  // 设置字体大小为12。
        .border({ width: 1 })  // 设置边框宽度为1。
        .padding(10)  // 设置内边距为10。
        .lineHeight(20)  // 设置行高为20。
    }.height(600).width(350).padding({ left: 35, right: 35, top: 35 })  // 设置容器的高度、宽度和内边距。
  }
}

以上代码预览如下:

1.2.4 容器组件-Column

Column容器组件是沿垂直方向布局的容器。该组件从API Version 7开始支持,从API version 9开始,该接口支持在ArkTS卡片中使用。其可以包含子组件。

1.2.4.1 用法

Column组件用法如下:

Column(value?: {space?: string | number})

以上参数解释如下:
在这里插入图片描述

Column组件支持很多通用属性,如:width、height等,还支持如下属性:
在这里插入图片描述

1.2.4.2 示例

以下代码定义了一个名为 ColumnExample 的组件,用于展示 Column 布局的不同特性,包括子元素间距、对齐方式和背景颜色。鸿蒙学习小助手V【hmos19】解答、咨询、项目实战

@Entry  // 使用 @Entry 装饰器标识这是一个入口组件。
@Component  // 使用 @Component 装饰器定义一个新组件。
struct ColumnExample {  // 定义名为 ColumnExample 的结构体,代表这个组件。

  build() {  // 定义 build 方法来构建UI。
    Column({ space: 5 }) {  // 创建一个 Column 组件,设置子元素间的垂直间距为5。
      Text('space').width('90%')  // 创建一个 Text 组件,说明接下来的内容与space属性相关。

      Column({ space: 5 }) {  // 创建一个内部 Column 组件,再次设置子元素间的垂直间距为5。
        Column().width('100%').height(30).backgroundColor(0xAFEEEE)  // 创建一个 Column 子组件,设置宽度、高度和背景颜色为浅蓝色。
        Column().width('100%').height(30).backgroundColor(0x00FFFF)  // 创建另一个 Column 子组件,设置宽度、高度和背景颜色为青色。
      }.width('90%').height(100).border({ width: 1 })  // 为这个内部 Column 设置宽度、高度和边框。

      // 设置子元素水平方向对齐方式
      Text('alignItems(Start)').width('90%')  // 创建一个 Text 组件,说明接下来的内容与水平起始对齐相关。
      Column() {  // 创建一个 Column 组件。
        Column().width('50%').height(30).backgroundColor(0xAFEEEE)  // 创建一个子 Column,设置宽度、高度和背景颜色为浅蓝色。
        Column().width('50%').height(30).backgroundColor(0x00FFFF)  // 创建另一个子 Column,设置宽度、高度和背景颜色为青色。
      }.alignItems(HorizontalAlign.Start).width('90%').border({ width: 1 })  // 为这个 Column 设置子元素水平起始对齐、宽度和边框。

      Text('alignItems(End)').width('90%')  // 创建一个 Text 组件,说明接下来的内容与水平结束对齐相关。
      Column() {  // 创建一个 Column 组件。
        Column().width('50%').height(30).backgroundColor(0xAFEEEE)  // 创建子 Column 组件,设置同上。
        Column().width('50%').height(30).backgroundColor(0x00FFFF)  // 创建另一个子 Column 组件,设置同上。
      }.alignItems(HorizontalAlign.End).width('90%').border({ width: 1 })  // 为这个 Column 设置子元素水平结束对齐、宽度和边框。

      Text('alignItems(Center)').width('90%')  // 创建一个 Text 组件,说明接下来的内容与水平居中对齐相关。
      Column() {  // 创建一个 Column 组件。
        Column().width('50%').height(30).backgroundColor(0xAFEEEE)  // 创建子 Column 组件,设置同上。
        Column().width('50%').height(30).backgroundColor(0x00FFFF)  // 创建另一个子 Column 组件,设置同上。
      }.alignItems(HorizontalAlign.Center).width('90%').border({ width: 1 })  // 为这个 Column 设置子元素水平居中对齐、宽度和边框。

      // 设置子元素垂直方向的对齐方式
      Text('justifyContent(Center)').width('90%')  // 创建一个 Text 组件,说明接下来的内容与垂直居中对齐相关。
      Column() {  // 创建一个 Column 组件。
        Column().width('90%').height(30).backgroundColor(0xAFEEEE)  // 创建子 Column 组件,设置宽度、高度和背景颜色为浅蓝色。
        Column().width('90%').height(30).backgroundColor(0x00FFFF)  // 创建另一个子 Column 组件,设置宽度、高度和背景颜色为青色。
      }.height(100).border({ width: 1 }).justifyContent(FlexAlign.Center)  // 为这个 Column 设置高度、边框和子元素垂直居中对齐。

      Text('justifyContent(End)').width('90%')  // 创建一个 Text 组件,说明接下来的内容与垂直结束对齐相关。
      Column() {  // 创建一个 Column 组件。
        Column().width('90%').height(30).backgroundColor(0xAFEEEE)  // 创建子 Column 组件,设置同上。
        Column().width('90%').height(30).backgroundColor(0x00FFFF)  // 创建另一个子 Column 组件,设置同上。
      }.height(100).border({ width: 1 }).justifyContent(FlexAlign.End)  // 为这个 Column 设置高度、边框和子元素垂直结束对齐。
    }.width('100%').padding({ top: 5 })  // 为最外层 Column 设置宽度和顶部内边距。
  }
}

以上代码预览如下:

1.2.5 组件组件-Row
Row容器组件是沿水平方向布局容器。该组件从API Version 7开始支持,从API version 9开始,该接口支持在ArkTS卡片中使用。可以包含子组件。

1.2.5.1 用法

Row用法如下:

Row(value?:{space?: number | string })

以上参数解释如下:

在这里插入图片描述

Row支持的属性如下:

在这里插入图片描述

更多示例可以加小助手获取…

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue 3 项目中如何使用 TypeScript 类型来优化 Vuex 的状态管理?

在 Vue 3 项目中&#xff0c;使用 TypeScript 可以极大地优化 Vuex 的状态管理&#xff0c;提供更强的类型检查和更好的开发体验。以下是一些使用 TypeScript 来优化 Vuex 状态管理的方法&#xff1a; 定义状态类型&#xff1a; 使用 TypeScript 的接口&#xff08;Interfaces&…

spring 集成 mybatis

spring 集成 mybatis 1、spring对junit的支持1.1、对junit4的支持1.2 对junit5的支持 2、Spring6集成MyBatis3.52.1 实现步骤2.2 实现 1、spring对junit的支持 1.1、对junit4的支持 依赖 <?xml version"1.0" encoding"UTF-8"?> <project xml…

Oracle获取对象的DDL创建语句

1.命令行方式&#xff08;如&#xff1a;sqlplus&#xff09; ## 用户 select dbms_metadata.get_ddl(USER,TEST) from dual;## 表 select dbms_metadata.get_ddl(TABLE,TEST,T1) from dual;## 表空间 select dbms_metadata.get_ddl(TABLESPACE,TBS_NAME) from dual;## 索引 s…

NetSuite 销售订单页面选择客户后停滞问题研究

随着用户环境中定制内容的增加&#xff0c;用户会发现Sales Order中选择Customer时的页面停滞时间会变长。这让用户感到很疑惑。 我们初步研究了一下这个问题&#xff0c;两个变量比较显著&#xff1a; •Form的页签数量•脚本的挂载数量 试验数据 1. 多页签&#xff0c;无…

prompt 工程整理(未完、持续更新)

工作期间会将阅读的论文、一些个人的理解整理到个人的文档中&#xff0c;久而久之就积累了不少“个人”能够看懂的脉络和提纲&#xff0c;于是近几日准备将这部分略显杂乱的内容重新进行梳理。论文部分以我个人的理解对其做了一些分类&#xff0c;并附上一些简短的理解&#xf…

【JavaEE多线程】理解和管理线程生命周期

目录 ThreadThread类的常用构造方法Thread类的常见属性启动一个线程-start()终止一个线程等待一个线程-join()线程的状态 Thread Thread 就是在 Java 中&#xff0c;线程的代言人。系统中的一个线程&#xff0c;就对应到 Java 中的一个 Thread 对象。围绕线程的各种操作&#…

Windows下安装myBase Desktop 8

下载 官网下载&#xff1a; Latest Version Downloads 安装 1.下载好安装包后&#xff0c;直接解压用鼠标双击安装文件“Mybase-Desktop-Ver8218-Win64.exe”进入安装向导 2.点击选择“Iaccept the agreement”同意相关协议,随后点击“next” 3.点击“next” 4.选择安装位置&am…

uni-app的页面中使用uni-map-common的地址解析(地址转坐标)功能,一直报请求云函数出错

想在uni-app的页面中使用uni-map-common的地址解析&#xff08;地址转坐标&#xff09;功能&#xff0c;怎么一直报请求云函数出错。 不看控制台啊,弄错了控制台&#xff0c;就说怎么一直没有打印出消息。 所以开始换高德地图的&#xff0c;昨天申请了两个 一开始用的第二个web…

Linux:Zabbix + Grafana10.4.2(3)

1.部署zabbix 下面这篇文章写了详细的部署zabbix过程 &#xff0c;使用的centos9系统 Linux&#xff1a;部署搭建zabbix6&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/137426966?spm1001.2014.3001.5501下面这篇文章使用的是centos7…

HBuilderX 的 CLI 命令行工具

1. cli 介绍 官方介绍&#xff1a;开发者可以通过 cli 命令行指示HBuilderX进行启动、打包、登录等操作 2. 快速启动 Mac 如果 shell 是 zsh&#xff0c;进入终端&#xff0c;在环境变量文件 ~/.zshrc 中添加以下内容&#xff0c;重新打开终端生效 alias hbopen $1 -a /Appli…

【蓝桥杯 2018 省】分数 题解(Excel+提交答案)

问题描述 求等比数列 1 / 1 1 / 2 1 / 4 1 / 8 1 / 16 … 1/1 1/2 1/4 1/8 1/16 \ldots 1/11/21/41/81/16… 的和&#xff0c;其中每项是前一项的一半&#xff0c;如果一共有20项&#xff0c;求这个和是多少&#xff0c;结果用分数表示出来。例如&#xff0c;对于前…

智慧公厕功能与应用

智慧公厕是智慧城市建设中极为重要的组成部分&#xff0c;它以其先进的功能和智能化的应用&#xff0c;为市民提供舒适、便利、安全的卫生设施。下面将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例项目现场实景实图实例&#xff0c;深入探讨智慧公厕的…

openGauss 之min/max 优化代码走读

一. 前言 在openGuass中&#xff0c;如果对索引列执行max/min操作,openGauss会优化成只读取索引的最前/后的一行数据&#xff0c;避免了对整表数据进行读取和聚合操作&#xff0c;如下所示&#xff1a; 二. min/max优化代码走读 1. 首先需要将min/max 算子转成成执行计划中降序…

ESP-IDF移植lvgl 驱动 ST7789

文章目录 1 前言2 准备3 移植LVGL3.1 工程准备3.2 修改 CMakeLists.txt文件编译 LVGL3.3 编译LVGL 4 编译 ST7789 LCD驱动5 发现问题 1 前言 本教程开始学习 LVGL的&#xff0c;开始之前要把环境配置好&#xff0c;首先就需要移植 lvgl&#xff0c;使用的是 esp32 环境&#xf…

vmware安装win10及ubuntu

安装win10 新建一个文件夹 选择刚才创建的文件夹 选择需要保存文件的位置&#xff0c;还是选择刚才创建的文件夹 选择自定义硬件 选择下载的win10镜像iso文件,导入后&#xff0c;点击完成即可 接下来就是下一步 没有此电脑&#xff0c;可以点击个性化-》主题-》桌面设置…

分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现SSA-LSSVM麻雀算法优化最小二乘支持向量机数据…

Nginx日志格式化和追踪

背景 Nginx是一款功能强大的Web服务器&#xff0c;对于网络环境中的日志记录和配置至关重要。定制化Nginx日志格式可以帮助管理员更好地监控服务器性能、分析用户行为并做出相应优化。在本文中&#xff0c;我们将深入探讨Nginx日志格式的高级定制化策略&#xff0c;包括理解基…

【Unity+Python】如何通过Socket进行通信

1、Unity端创建名为UnityClient.cs脚本代码(客户端)&#xff1a; 注意&#xff1a;unity的规则中类&#xff0c;名和脚本文件名需要相同。 using System.Net.Sockets; using System.Text; using UnityEngine;public class UnityClient : MonoBehaviour {TcpClient client;Netw…

全景剖析SSD SLC Cache缓存设计原理-2

四、SLC缓存对SSD的寿命是否有优化&#xff1f; 当使用QLC或TLC NAND闪存并将其切换到SLC模式进行写入时&#xff0c;会对闪存的寿命产生以下影响&#xff1a; 短期寿命提升&#xff1a; SLC模式下&#xff0c;每个存储单元仅存储一个比特数据&#xff0c;相对于QLC或TLC来说…

在 Elasticsearch 中扩展 ML 推理管道:如何避免问题并解决瓶颈

作者&#xff1a;来自 Elastic Iulia Feroli 是时候考虑语义搜索运营了吗&#xff1f; 无论你是一位经验丰富的搜索工程师&#xff0c;希望探索新的人工智能功能&#xff0c;还是一位机器学习专家&#xff0c;希望更多地利用搜索基础设施来增强语义相似性模型 —— 充分利用这…