当前位置:   article > 正文

鸿蒙HarmonyOS实战-ArkTS语言(基本语法)_arkts promise

arkts promise

 一、ArkTS语言基本语法

1.简介

HarmonyOS的ArkTS语言是一种基于TypeScript开发的语言,它专为HarmonyOS系统开发而设计。ArkTS语言结合了JavaScript的灵活性和TypeScript的严谨性,使得开发者能够快速、高效地开发出高质量的HarmonyOS应用程序。

ArkTS语言具有以下特点:

  1. 静态类型检查:开发者在编写代码时可以使用类型注解来进行类型检查,从而减少因类型错误而导致的bug。

  2. 异步/同步编程:ArkTS语言支持基于Promise和async/await的异步/同步编程方式,能够更好地处理异步操作。

  3. 内置模块:ArkTS语言内置了许多常用的模块,如文件系统、网络请求、图形渲染等,使得开发者不必自己编写这些模块。

  4. 兼容性:ArkTS语言使用TypeScript语法,可以与JavaScript代码无缝集成,并且可以编译成JavaScript代码来在其他平台上运行。

ArkTS语言基础类库是HarmonyOS系统上为应用开发者提供的常用基础能力,主要包含能力如下图所示:

在这里插入图片描述
ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。

ArkTS和HTML的差别:
在这里插入图片描述
在这里插入图片描述

2.TypeScript的基础语法

TypeScript是一种由微软开发的JavaScript超集语言,它支持JavaScript的所有语法,但添加了一些新的特性和语法,使开发更加可靠和高效。TypeScript最大的特点是引入了静态类型,开发者可以在编译时发现类型错误,提高代码的可维护性和可读性。

TypeScript代码可以在编译时被转换成JavaScript代码,在浏览器和Node.js环境下都可以运行。虽然TypeScript相对于JavaScript来说更加复杂,但是它可以帮助开发者更好地组织和管理复杂的项目,特别是在团队协作中提高代码的质量和可维护性。

TypeScript基础知识包括基本类型、变量声明、函数、类、接口、泛型等。另外,TypeScript还支持模块化开发,可以使用ES模块规范或者CommonJS规范导入和导出模块。在实际项目开发中,TypeScript还可以结合工具链如Webpack、Babel进行编译、打包等操作。

在这里插入图片描述
除了上面提到的变量声明、函数定义、类定义、接口定义和枚举类型外,TypeScript还有一些基础语法需要掌握:

2.1 类型注解

TypeScript的静态类型检查是通过类型注解实现的。在声明变量或函数时,可以使用冒号加上类型注解,指定变量或函数的类型。例如:

  1. let name: string = "TypeScript";
  2. function add(a: number, b: number): number {
  3. return a + b;
  4. }

2.2 接口

TypeScript的接口是用来描述对象的形状的。可以定义对象需要包含哪些属性和方法,以及它们的类型。例如:

  1. interface Person {
  2. name: string;
  3. age: number;
  4. sayHello(): void;
  5. }
  6. let tom: Person = {
  7. name: "Tom",
  8. age: 18,
  9. sayHello: function() {
  10. console.log(`Hello, my name is ${this.name}!`);
  11. }
  12. };

2.3 泛型

TypeScript的泛型可以帮助我们编写更加灵活、可重用的代码。它允许在编写函数、类或接口时使用参数化类型,从而提高代码的通用性和可读性。例如:

  1. function identity<T>(arg: T): T {
  2. return arg;
  3. }
  4. let output = identity<string>("TypeScript");
  5. console.log(output); // 输出 TypeScript

2.4 类的继承

TypeScript的类可以继承其他类,从而实现代码的重用和扩展。通过关键字extends可以让一个类继承另一个类,并继承其属性和方法。例如:

  1. class Animal {
  2. name: string;
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. move(distance: number = 0) {
  7. console.log(`${this.name} moved ${distance}m.`);
  8. }
  9. }
  10. class Dog extends Animal {
  11. bark() {
  12. console.log("Woof! Woof!");
  13. }
  14. }
  15. let dog = new Dog("Bobby");
  16. dog.move(10); // 输出 "Bobby moved 10m."
  17. dog.bark(); // 输出 "Woof! Woof!"

2.5 类的访问修饰符

TypeScript的类可以通过访问修饰符来控制类的属性和方法的访问权限。有三个访问修饰符可以使用:publicprivateprotected。默认情况下,都是public

public:公共的,任何外部或内部都可以访问。

private:私有的,只有类的内部可以访问,外部无法访问。

protected:受保护的,只有类的内部和其子类可以访问,外部无法访问。

  1. class Person {
  2. protected name: string;
  3. constructor(name: string) {
  4. this.name = name;
  5. }
  6. protected sayHello() {
  7. console.log(`Hello, I'm ${this.name}.`);
  8. }
  9. }
  10. class Student extends Person {
  11. constructor(name: string) {
  12. super(name);
  13. }
  14. public sayHelloToTeacher(teacher: Person) {
  15. console.log(`Hello, ${teacher.name}, I'm ${this.name}.`);
  16. }
  17. }
  18. let tom = new Student("Tom");
  19. let bob = new Person("Bob");
  20. tom.sayHelloToTeacher(bob); // 输出 "Hello, Bob, I'm Tom."
  21. bob.sayHello(); // 报错:属性 'sayHello' 受保护,只能在类 'Person' 及其子类中访问。

以上只是举例一些TS的基础语法,TS内容远不止这些不懂的可以去学学TS。

3.ArkTS的基本组成

在这里插入图片描述

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

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

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

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

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

  • 事件方法:组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()。
    系统组件、属性方法、事件方法具体使用可参考基于ArkTS的声明式开发范式。

除此之外,ArkTS扩展了多种语法范式来使开发更加便捷:

  • @Builder/@BuilderParam:特殊的封装UI描述的方法,细粒度的封装和复用UI描述。
  • @Extend/@Style:扩展内置组件和封装属性样式,更灵活地组合内置组件。
  • stateStyles:多态样式,可以依据组件的内部状态的不同,设置不同样式。

4.自定义组件

  1. @Component
  2. struct HelloComponent {
  3. @State message: string = 'Hello, World!';
  4. build() {
  5. // HelloComponent自定义组件组合系统组件Row和Text
  6. Row() {
  7. Text(this.message)
  8. .onClick(() => {
  9. // 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'
  10. this.message = 'Hello, ArkUI!';
  11. })
  12. }
  13. }
  14. }
  15. @Entry
  16. @Component
  17. struct ParentComponent {
  18. build() {
  19. Column() {
  20. Text('ArkUI message')
  21. HelloComponent({ message: 'Hello, World!' });
  22. Divider()
  23. HelloComponent({ message: '你好!' });
  24. }
  25. }
  26. }
  • struct:自定义组件基于struct实现,struct + 自定义组件名 +
    {…}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。

  • build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。

  • @Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。@Entry可以接受一个可选的LocalStorage的参数。

4.1 build()函数规范

1、根节点唯一

  1. @Entry
  2. @Component
  3. struct MyComponent {
  4. build() {
  5. // 根节点唯一且必要,必须为容器组件
  6. Row() {
  7. ChildComponent()
  8. }
  9. }
  10. }
  11. @Component
  12. struct ChildComponent {
  13. build() {
  14. // 根节点唯一且必要,可为非容器组件
  15. Image('test.jpg')
  16. }
  17. }

2、不允许声明本地变量、打印、作用域

  1. build() {
  2. // 反例:不允许声明本地变量
  3. let a: number = 1;
  4. // 反例:不允许console.info
  5. console.info('print debug log');
  6. // 反例:不允许本地作用域
  7. {
  8. ...
  9. }
  10. }

3、不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值。

  1. @Component
  2. struct ParentComponent {
  3. doSomeCalculations() {
  4. }
  5. calcTextValue(): string {
  6. return 'Hello World';
  7. }
  8. @Builder doSomeRender() {
  9. Text(`Hello World`)
  10. }
  11. build() {
  12. Column() {
  13. // 反例:不能调用没有用@Builder装饰的方法
  14. this.doSomeCalculations();
  15. // 正例:可以调用
  16. this.doSomeRender();
  17. // 正例:参数可以为调用TS方法的返回值
  18. Text(this.calcTextValue())
  19. }
  20. }
  21. }

4、不允许switch和表达式

  1. build() {
  2. Column() {
  3. // 反例:不允许使用switch语法
  4. switch (expression) {
  5. case 1:
  6. Text('...')
  7. break;
  8. case 2:
  9. Image('...')
  10. break;
  11. default:
  12. Text('...')
  13. break;
  14. }
  15. // 反例:不允许使用表达式
  16. (this.aVar > 10) ? Text('...') : Image('...')
  17. }
  18. }

5.页面和自定义组件生命周期

在这里插入图片描述
页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:

  • onPageShow:页面每次显示时触发。
  • onPageHide:页面每次隐藏时触发一次。
  • onBackPress:当用户点击返回按钮时触发。

组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • aboutToDisappear:在自定义组件即将析构销毁时执行。
  1. // Index.ets
  2. import router from '@ohos.router';
  3. @Entry
  4. @Component
  5. struct MyComponent {
  6. @State showChild: boolean = true;
  7. // 只有被@Entry装饰的组件才可以调用页面的生命周期
  8. onPageShow() {
  9. console.info('Index onPageShow');
  10. }
  11. // 只有被@Entry装饰的组件才可以调用页面的生命周期
  12. onPageHide() {
  13. console.info('Index onPageHide');
  14. }
  15. // 只有被@Entry装饰的组件才可以调用页面的生命周期
  16. onBackPress() {
  17. console.info('Index onBackPress');
  18. }
  19. // 组件生命周期
  20. aboutToAppear() {
  21. console.info('MyComponent aboutToAppear');
  22. }
  23. // 组件生命周期
  24. aboutToDisappear() {
  25. console.info('MyComponent aboutToDisappear');
  26. }
  27. build() {
  28. Column() {
  29. // this.showChild为true,创建Child子组件,执行Child aboutToAppear
  30. if (this.showChild) {
  31. Child()
  32. }
  33. // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
  34. Button('create or delete Child').onClick(() => {
  35. this.showChild = false;
  36. })
  37. // push到Page2页面,执行onPageHide
  38. Button('push to next page')
  39. .onClick(() => {
  40. router.pushUrl({ url: 'pages/Page2' });
  41. })
  42. }
  43. }
  44. }
  45. @Component
  46. struct Child {
  47. @State title: string = 'Hello World';
  48. // 组件生命周期
  49. aboutToDisappear() {
  50. console.info('[lifeCycle] Child aboutToDisappear')
  51. }
  52. // 组件生命周期
  53. aboutToAppear() {
  54. console.info('[lifeCycle] Child aboutToAppear')
  55. }
  56. build() {
  57. Text(this.title).fontSize(50).onClick(() => {
  58. this.title = 'Hello ArkUI';
  59. })
  60. }
  61. }

6.装饰函数

6.1 @Builder装饰器

@Builder主要是定义页面UI

6.1.1 装饰指向

1、自定义组件内自定义构建函数

  1. @Builder MyBuilderFunction(){ ... }
  2. #使用
  3. this.MyBuilderFunction(){ ... }

2、MyGlobalBuilderFunction()

  1. @Builder function MyGlobalBuilderFunction(){ ... }
  2. #使用
  3. MyGlobalBuilderFunction()
6.1.2 参数传递

1、按引用传递参数

  1. @Builder function ABuilder($$: { paramA1: string }) {
  2. Row() {
  3. Text(`UseStateVarByReference: ${$$.paramA1} `)
  4. }
  5. }
  6. @Entry
  7. @Component
  8. struct Parent {
  9. @State label: string = 'Hello';
  10. build() {
  11. Column() {
  12. // 在Parent组件中调用ABuilder的时候,将this.label引用传递给ABuilder
  13. ABuilder({ paramA1: this.label })
  14. Button('Click me').onClick(() => {
  15. // 点击“Click me”后,UI从“Hello”刷新为“ArkUI”
  16. this.label = 'ArkUI';
  17. })
  18. }
  19. }
  20. }

2、按值传递参数

  1. @Builder function ABuilder(paramA1: string) {
  2. Row() {
  3. Text(`UseStateVarByValue: ${paramA1} `)
  4. }
  5. }
  6. @Entry
  7. @Component
  8. struct Parent {
  9. label: string = 'Hello';
  10. build() {
  11. Column() {
  12. ABuilder(this.label)
  13. }
  14. }
  15. }

6.2 @BuilderParam装饰器

@BuilderParam用来装饰指向@Builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。

6.2.1 装饰指向

1、本地初始化@BuilderParam

  1. @Builder function GlobalBuilder0() {}
  2. @Component
  3. struct Child {
  4. @Builder doNothingBuilder() {};
  5. @BuilderParam aBuilder0: () => void = this.doNothingBuilder;
  6. @BuilderParam aBuilder1: () => void = GlobalBuilder0;
  7. build(){}
  8. }

2、初始化子组件@BuilderParam

  1. @Component
  2. struct Child {
  3. @BuilderParam aBuilder0: () => void;
  4. build() {
  5. Column() {
  6. this.aBuilder0()
  7. }
  8. }
  9. }
  10. @Entry
  11. @Component
  12. struct Parent {
  13. @Builder componentBuilder() {
  14. Text(`Parent builder `)
  15. }
  16. build() {
  17. Column() {
  18. Child({ aBuilder0: this.componentBuilder })
  19. }
  20. }
  21. }

this都是器其本身,不会存在传递。

6.2.2 使用场景

1、参数化传递

  1. @Builder function GlobalBuilder1($$ : {label: string }) {
  2. Text($$.label)
  3. .width(400)
  4. .height(50)
  5. .backgroundColor(Color.Blue)
  6. }
  7. @Component
  8. struct Child {
  9. label: string = 'Child'
  10. // 无参数类,指向的componentBuilder也是无参数类型
  11. @BuilderParam aBuilder0: () => void;
  12. // 有参数类型,指向的GlobalBuilder1也是有参数类型的方法
  13. @BuilderParam aBuilder1: ($$ : { label : string}) => void;
  14. build() {
  15. Column() {
  16. this.aBuilder0()
  17. this.aBuilder1({label: 'global Builder label' } )
  18. }
  19. }
  20. }
  21. @Entry
  22. @Component
  23. struct Parent {
  24. label: string = 'Parent'
  25. @Builder componentBuilder() {
  26. Text(`${this.label}`)
  27. }
  28. build() {
  29. Column() {
  30. this.componentBuilder()
  31. Child({ aBuilder0: this.componentBuilder, aBuilder1: GlobalBuilder1 })
  32. }
  33. }
  34. }

2、尾随闭包

  1. // xxx.ets
  2. @Component
  3. struct CustomContainer {
  4. @Prop header: string;
  5. @BuilderParam closer: () => void
  6. build() {
  7. Column() {
  8. Text(this.header)
  9. .fontSize(30)
  10. this.closer()
  11. }
  12. }
  13. }
  14. @Builder function specificParam(label1: string, label2: string) {
  15. Column() {
  16. Text(label1)
  17. .fontSize(30)
  18. Text(label2)
  19. .fontSize(30)
  20. }
  21. }
  22. @Entry
  23. @Component
  24. struct CustomContainerUser {
  25. @State text: string = 'header';
  26. build() {
  27. Column() {
  28. // 创建CustomContainer,在创建CustomContainer时,通过其后紧跟一个大括号“{}”形成尾随闭包
  29. // 作为传递给子组件CustomContainer @BuilderParam closer: () => void的参数
  30. CustomContainer({ header: this.text }) {
  31. Column() {
  32. specificParam('testA', 'testB')
  33. }.backgroundColor(Color.Yellow)
  34. .onClick(() => {
  35. this.text = 'changeHeader';
  36. })
  37. }
  38. }
  39. }
  40. }

6.3 @Styles装饰器

@Styles装饰器主要是定义公共样式

6.3.1 装饰指向

1、全局

  1. // 全局
  2. @Styles function functionName() { ... }
  3. // 在组件内
  4. @Component
  5. struct FancyUse {
  6. @Styles fancy() {
  7. .height(100)
  8. }
  9. }

2、组件内

  1. @Component
  2. struct FancyUse {
  3. @State heightValue: number = 100
  4. @Styles fancy() {
  5. .height(this.heightValue)
  6. .backgroundColor(Color.Yellow)
  7. .onClick(() => {
  8. this.heightValue = 200
  9. })
  10. }
  11. }
6.3.2 使用场景
  1. // 定义在全局的@Styles封装的样式
  2. @Styles function globalFancy () {
  3. .width(150)
  4. .height(100)
  5. .backgroundColor(Color.Pink)
  6. }
  7. @Entry
  8. @Component
  9. struct FancyUse {
  10. @State heightValue: number = 100
  11. // 定义在组件内的@Styles封装的样式
  12. @Styles fancy() {
  13. .width(200)
  14. .height(this.heightValue)
  15. .backgroundColor(Color.Yellow)
  16. .onClick(() => {
  17. this.heightValue = 200
  18. })
  19. }
  20. build() {
  21. Column({ space: 10 }) {
  22. // 使用全局的@Styles封装的样式
  23. Text('FancyA')
  24. .globalFancy ()
  25. .fontSize(30)
  26. // 使用组件内的@Styles封装的样式
  27. Text('FancyB')
  28. .fancy()
  29. .fontSize(30)
  30. }
  31. }
  32. }

6.4 @Extend装饰器

@Extend用于扩展原生组件样式,作用和@Styles差不多。

6.4.1 装饰指向

@Extend仅支持定义在全局,不支持在组件内部定义

1、@Extend支持封装指定的组件的私有属性和私有事件

  1. // @Extend(Text)可以支持Text的私有属性fontColor
  2. @Extend(Text) function fancy () {
  3. .fontColor(Color.Red)
  4. }
  5. // superFancyText可以调用预定义的fancy
  6. @Extend(Text) function superFancyText(size:number) {
  7. .fontSize(size)
  8. .fancy()
  9. }

2、@Extend装饰的方法支持参数

  1. // xxx.ets
  2. @Extend(Text) function fancy (fontSize: number) {
  3. .fontColor(Color.Red)
  4. .fontSize(fontSize)
  5. }
  6. @Entry
  7. @Component
  8. struct FancyUse {
  9. build() {
  10. Row({ space: 10 }) {
  11. Text('Fancy')
  12. .fancy(16)
  13. Text('Fancy')
  14. .fancy(24)
  15. }
  16. }
  17. }

3、@Extend装饰的方法的参数可以为function

  1. @Extend(Text) function makeMeClick(onClick: () => void) {
  2. .backgroundColor(Color.Blue)
  3. .onClick(onClick)
  4. }
  5. @Entry
  6. @Component
  7. struct FancyUse {
  8. @State label: string = 'Hello World';
  9. onClickHandler() {
  10. this.label = 'Hello ArkUI';
  11. }
  12. build() {
  13. Row({ space: 10 }) {
  14. Text(`${this.label}`)
  15. .makeMeClick(this.onClickHandler.bind(this))
  16. }
  17. }
  18. }

4、@Extend的参数可以为状态变量

  1. @Extend(Text) function fancy (fontSize: number) {
  2. .fontColor(Color.Red)
  3. .fontSize(fontSize)
  4. }
  5. @Entry
  6. @Component
  7. struct FancyUse {
  8. @State fontSizeValue: number = 20
  9. build() {
  10. Row({ space: 10 }) {
  11. Text('Fancy')
  12. .fancy(this.fontSizeValue)
  13. .onClick(() => {
  14. this.fontSizeValue = 30
  15. })
  16. }
  17. }
  18. }
☀️6.4.2 使用场景
  1. @Extend(Text) function fancyText(weightValue: number, color: Color) {
  2. .fontStyle(FontStyle.Italic)
  3. .fontWeight(weightValue)
  4. .backgroundColor(color)
  5. }
  6. @Entry
  7. @Component
  8. struct FancyUse {
  9. @State label: string = 'Hello World'
  10. build() {
  11. Row({ space: 10 }) {
  12. Text(`${this.label}`)
  13. .fancyText(100, Color.Blue)
  14. Text(`${this.label}`)
  15. .fancyText(200, Color.Pink)
  16. Text(`${this.label}`)
  17. .fancyText(300, Color.Orange)
  18. }.margin('20%')
  19. }
  20. }

7.多态样式

stateStyles是属性方法,可以根据UI内部状态来设置样式,类似于css伪类,但语法不同。ArkUI提供以下四种状态:

  • focused:获焦态
  • normal:正常态
  • pressed:按压态
  • disabled:不可用态

7.1 基本使用

  1. @Entry
  2. @Component
  3. struct CompWithInlineStateStyles {
  4. @State focusedColor: Color = Color.Red;
  5. normalColor: Color = Color.Green
  6. build() {
  7. Column() {
  8. Button('clickMe').height(100).width(100)
  9. .stateStyles({
  10. normal: {
  11. .backgroundColor(this.normalColor)
  12. },
  13. focused: {
  14. .backgroundColor(this.focusedColor)
  15. }
  16. })
  17. .onClick(() => {
  18. this.focusedColor = Color.Pink
  19. })
  20. .margin('30%')
  21. }
  22. }
  23. }

7.2 @Styles和stateStyles联合使用

  1. @Entry
  2. @Component
  3. struct MyComponent {
  4. @Styles normalStyle() {
  5. .backgroundColor(Color.Gray)
  6. }
  7. @Styles pressedStyle() {
  8. .backgroundColor(Color.Red)
  9. }
  10. build() {
  11. Column() {
  12. Text('Text1')
  13. .fontSize(50)
  14. .fontColor(Color.White)
  15. .stateStyles({
  16. normal: this.normalStyle,
  17. pressed: this.pressedStyle,
  18. })
  19. }
  20. }
  21. }

7.3 stateStyles里使用常规变量和状态变量

  1. @Entry
  2. @Component
  3. struct CompWithInlineStateStyles {
  4. @State focusedColor: Color = Color.Red;
  5. normalColor: Color = Color.Green
  6. build() {
  7. Button('clickMe').height(100).width(100)
  8. .stateStyles({
  9. normal: {
  10. .backgroundColor(this.normalColor)
  11. },
  12. focused: {
  13. .backgroundColor(this.focusedColor)
  14. }
  15. })
  16. .onClick(() => {
  17. this.focusedColor = Color.Pink
  18. })
  19. .margin('30%')
  20. }
  21. }

 
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/92070

推荐阅读
相关标签