ArkTS

TypeScript语法

基本语法

视频教程
image.png

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

基础

let 、const、var
作用域: var是函数作用域,这意味着如果你在函数内部使用 var 声明一个变量,那么这个变量在整个函数内部都可以访问。而 let 是块级作用域,只能在声明它的块或子块中访问。
使用 let 可以减少由于编程错误或误解引起的bug数量,并且强制执行更强大、更易理解、更可预测的编程模式。

TypeScript 提供了 string 关键字来表示字符串类型,使用单引号(')或双引号(")来表示字符串类型,也可以使用反引号(**`**)来定义多行文本和内嵌表达式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
//元组
let x: [string, number];
x = ['hello', 10]; // OK
x = [10, 'hello']; // Error

enum Color {Red, Green, Blue};
let c: Color = Color.Green;

let notSure: unknown = 4;
notSure = 'maybe a string instead';
notSure = false;

function test(): void {
console.log('This is function is void');
}

可选参数

1
2
3
4
5
6
7
8
9
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + ' ' + lastName;
else
return firstName;
}

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

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

1
2
3
( [param1, parma2,…param n] )=> {
// 代码块
}

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

1
2
3
let arrowFun = ( [param1, parma2,…param n] )=> {
// 代码块
}

类:和Java类似,有new、extends、this、public、private、protected

1
2
3
4
5
6
7
8
9
10
11
12
13
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}`;
}
}

for..of和for..in均可迭代一个列表,但是用于迭代的值却不同:for..in迭代的是对象的键,而for..of则迭代的是对象的值。

1
2
3
4
5
6
7
8
9
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"
}

module

随着应用越来越大,通常要将代码拆分成多个文件,即所谓的模块(module)
两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 { NewsData } from '../common/bean/NewsData';

ArkTS

基本UI描述

  • 装饰器:用来装饰类、结构体、方法以及变量,赋予其特殊的含义,如上述示例中 @Entry 、 @Component 、 @State 都是装饰器。具体而言, @Component 表示这是个自定义组件; @Entry 则表示这是个入口组件; @State 表示组件中的状态变量,这个状态变化会引起 UI 变更。
  • 自定义组件:可复用的 UI 单元,可组合其它组件,如上述被 @Component 装饰的 struct Hello。

ArkTS通过装饰器@Component和@Entry装饰struct关键字声明的数据结构,构成一个自定义组件。自定义组件中提供了一个build函数,开发者需在该函数内以链式调用的方式进行基本的UI描述,UI描述的方法请参考UI描述规范。

基本概念

  • *struct:自定义组件可以基于struct实现,不能有继承关系,对于struct的实例化,可以省略new。
  • *装饰器:装饰器给被装饰的对象赋予某一种能力,其不仅可以装饰类或结构体,还可以装饰类的属性。多个装饰器可以叠加到目标元素上,定义在同一行中或者分开多行,推荐分开多行定义。
    1
    2
    3
    4
    @Entry
    @Component
    struct MyComponent {
    }
  • @Component:装饰struct,结构体在装饰后具有基于组件的能力,需要实现build方法来创建UI。
  • @Entry: 装饰struct,组件被装饰后作为页面的入口,页面加载时将被渲染显示
  • @Preview:装饰struct, 用@Preview装饰的自定义组件可以在DevEco Studio的预览器上进行实时预览,加载页面时,将创建并显示@Preview装饰的自定义组件。

状态管理

基本概念-状态管理-ArkTS语法(声明式UI)-学习ArkTS语言-开发基础知识-入门-HarmonyOS应用开发
ArkTS提供了多维度的状态管理机制,在UI开发框架中,和UI相关联的数据,不仅可以在组件内使用,还可以在不同组件层级间传递,比如父子组件之间、爷孙组件之间,也可以是全局范围内的传递。另外,从数据的传递形式来看,可分为只读的单向传递和可变更的双向传递

页面级变量的状态管理

页面级变量的状态管理-状态管理-ArkTS语法(声明式UI)-学习ArkTS语言-开发基础知识-入门-HarmonyOS应用开发

@State

@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新

  • 支持多种类型数据:支持class、number、boolean、string强类型数据的值类型和引用类型,不支持object和any
  • 内部私有:标记为@State的属性是私有变量,只能在组件内访问
  • 需要本地初始化:必须为所有@State变量分配初始值

@Prop

@Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但变量的更改不会通知给父组件,父组件变量的更改会同步到@prop装饰的变量,即@Prop属于单向数据绑定
@Prop状态数据具有以下特征:

  • 支持简单类型:仅支持number、string、boolean等简单数据类型;
  • 私有:仅支持组件内访问;
  • 支持多个实例:一个组件中可以定义多个标有@Prop的属性;
  • 创建自定义组件时将值传递给@Prop变量进行初始化:在创建组件的新实例时,必须初始化所有@Prop变量,不支持在组件内部进行初始化

==实现子组件从父子组件单向状态同步 : @State和@Prop==

@Link装饰的变量可以和父组件的@State变量建立双向数据绑定,@Link变量不能在组件内部进行初始化。
我们对于视图更新,可以使用@State 标记变量,但是@State不能进行跨文件使用。这个时候@Link的实现就弥补了@State的不足。使用@Link的话。子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。

==子组件@Link装饰的变量可以和父组件的@State变量建立双向数据绑定。==

@Observed和ObjectLink数据管理

当开发者只想针对父组件中某个数据对象的部分信息进行同步时,使用@Link就不能满足要求。如果这些部分信息是一个类对象,就可以使用@ObjectLink配合@Observed来实现,如下图所示。

  • @Observed用于类,@ObjectLink用于变量。
  • @ObjectLink装饰的变量类型必须为类(class type)。
    • 类要被@Observed装饰器所装饰。
    • 不支持简单类型参数,可以使用@Prop进行单向同步。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      // xxx.ets
      // 父组件ViewB中的类对象ClassA与子组件ViewA保持数据同步时,可以使用@ObjectLink和@Observed,绑定该数据对象的父组件和其他子组件同步更新
      var nextID: number = 0

      @Observed
      class ClassA {
      public name: string
      public c: number
      public id: number

      constructor(c: number, name: string = 'OK') {
      this.name = name
      this.c = c
      this.id = nextID++
      }
      }

      @Component
      struct ViewA {
      label: string = 'ViewA1'
      @ObjectLink a: ClassA

      build() {
      Row() {
      Button(`ViewA [${this.label}] this.a.c= ${this.a.c} +1`)
      .onClick(() => {
      this.a.c += 1
      })
      }.margin({ top: 10 })
      }
      }

      @Entry
      @Component
      struct ViewB {
      @State arrA: ClassA[] = [new ClassA(0), new ClassA(0)]

      build() {
      Column() {
      ForEach(this.arrA, (item) => {
      ViewA({ label: `#${item.id}`, a: item })
      }, (item) => item.id.toString())
      ViewA({ label: `this.arrA[first]`, a: this.arrA[0] })
      ViewA({ label: `this.arrA[last]`, a: this.arrA[this.arrA.length - 1] })

      Button(`ViewB: reset array`)
      .margin({ top: 10 })
      .onClick(() => {
      this.arrA = [new ClassA(0), new ClassA(0)]
      })
      Button(`ViewB: push`)
      .margin({ top: 10 })
      .onClick(() => {
      this.arrA.push(new ClassA(0))
      })
      Button(`ViewB: shift`)
      .margin({ top: 10 })
      .onClick(() => {
      this.arrA.shift()
      })
      }.width('100%')
      }
      }

@Consume和@Provide

@Provide作为数据的提供方,可以更新其子孙节点的数据,并触发页面渲染。@Consume在感知到@Provide数据的更新后,会触发当前自定义组件的重新渲染。

应用级变量的状态管理

应用级变量的状态管理-状态管理-ArkTS语法(声明式UI)-学习ArkTS语言-开发基础知识-入门-HarmonyOS应用开发


ArkTS
http://peiniwan.github.io/2025/12/0ccc710c28c2.html
作者
六月的雨
发布于
2025年12月16日
许可协议