文章

ArkTS 基础语法深度解析

鸿蒙主力语言 ArkTS:在 TypeScript 基础上的声明式 UI、严格类型与特有语法。 讲清基础语法与和 TS 的差异,掌握后能答出「ArkTS 为什么限制更严」。

ArkTS 基础语法深度解析

一句话概括

ArkTS = TypeScript 的子集 + 声明式 UI + 响应式状态管理。它是鸿蒙原生开发的官方语言,前端开发者能迅速上手,但它的严格禁 any、禁动态属性、禁 prototype 只为一个目的——编译出原生级别的性能。

核心知识点

1. struct + @Component:组件的骨架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Entry  // @Entry 标记为应用入口
@Component  // @Component 标记为 UI 组件
struct CounterApp {
  @State count: number = 0;

  build() {
    Column() {
      Text('计数: ' + this.count)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)

      Button('增加')
        .onClick(() => { this.count++; })  // 直接改 State,UI 自动更新
    }
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

关键:ArkTS 用 struct(不是 class)定义组件——struct 是值类型,编译器能更激进地优化内存布局。这点和 Flutter 的 Widget(不可变对象)思路不同——ArkTS 的 struct 组件本身持有可变状态。

1
2
3
4
5
6
7
8
9
10
// @State:组件自己的状态,改了自动刷新 UI
@State count: number = 0;

// @Prop:从父组件传入,只读
@Prop name: string;

// @Link:从父组件传入引用,双向同步,父组件用 $ 前缀传
// 父:TodoItem({ task: $task })
// 子:
@Link task: Task;

对比速记:@State = 私有状态,@Prop = 只读 props,@Link = Vue 的 v-model。

3. 声明式 UI:if / ForEach / @Builder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 条件渲染 —— 直接用 if 语句,不需要三元表达式
if (this.isOnline) {
  Circle().width(12).height(12).fill(Color.Green)
}

// 循环渲染 —— ForEach,第三个参数是 key 生成器
ForEach(this.items, (item: string) => {
  Text(item).fontSize(16)
}, (item: string) => item)

// 可复用构建函数
@Builder ProductCard(p: Product) {
  Row() {
    Image(p.thumbnail).width(80).height(80).borderRadius(8)
    Text(p.name).fontSize(16).fontWeight(FontWeight.Bold)
  }
}

@Builder 和普通函数的区别:@Builder 能用状态变量,变量变了自动更新。

4. 生命周期钩子

1
2
3
4
aboutToAppear()    // 组件即将显示 → 初始化(类似 Flutter initState + mount)
aboutToDisappear() // 组件即将销毁 → 释放资源(类似 Flutter dispose)
onPageShow()       // 页面显示(包括从后台返回)
onPageHide()       // 页面隐藏(切后台或导航走)

不需要 override 关键字,框架自动识别这些方法名。

5. ArkTS vs TypeScript:哪些东西不能写

1
2
3
4
let x: any = 'hello';     // ❌ 禁 any
let y: unknown = 42;      // ❌ 禁 unknown
obj.newProp = 'hi';       // ❌ 禁动态属性
String.prototype.foo = …; // ❌ 禁 prototype 修改

不让用的都是性能杀手。编译器需要确切类型信息来生成高效 AOT 代码。

其实你每天都在用

  • 计数器 / 表单切换 — @State + onClick 改值,UI 自动刷新——零模板代码
  • 列表 + 详情页通信 — 父组件 @State items,子组件 @Link task 双向同步
  • 条件 UI — 登录前显示登录按钮、登录后显示用户信息,全凭 if 语句控制
  • 深色模式 — @StorageProp('theme') 全局存主题,所有组件自动跟随
  • 页面进场动画 — aboutToAppear 里启动动画,aboutToDisappear 里停掉

常见误解(FAQ)

  • ❌ 误区:「ArkTS 就是 TypeScript 套了一个 UI 框架」 ArkTS 是 TypeScript 的严格子集 + 编译器级扩展。@State 会被编译器转化为响应式依赖追踪代码——这不是运行时框架,是编译时注入。你不写 any 不是因为风格不好,是编译器需要完整的类型信息做 AOT 优化。

  • ❌ 误区:「@Prop 和 @Link 用哪个都一样」 @Prop 是值拷贝(单向),@Link 是引用(双向)。父组件给子传 $count 时,子改了 count 父也变——这是 @Link 的能力。@Prop 的变量子组件改了也不会同步回父组件。

  • ❌ 误区:「ArkTS 和 Flutter 是同类框架所以可以互相替代」 底层完全不同。ArkTS 跑在鸿蒙自研渲染引擎上,Flutter 跑在 Skia/Impeller 上。语法像不代表架构像——ArkTS 的 struct 持有可变状态,Flutter 的 Widget 是不可变的。

  • ❌ 误区:「async/await 写法一样,性能也一样」 ArkTS 的异步基于鸿蒙的 TaskPool 不是 Dart 的 Event Loop。大量并发异步任务时,调度策略和线程模型都不同——别从 Flutter 的习惯照搬。

一句话总结

ArkTS = TypeScript 的功能砍掉 any,再加上 @State / @Component / @Builder 三个装饰器。前端开发者最熟悉的语法 + 原生级别的编译优化——这就是鸿蒙为什么选择这条路。

本文由作者按照 CC BY 4.0 进行授权