对照typescript学习鸿蒙ArkTS

HarmonyOS选择ArkTS的原因

  1. TypeScript超集:ArkTS是TypeScript的超集,保留了TypeScript的核心特性,降低了开发者的学习成本,使得熟悉TypeScript的开发者能够快速上手。

  2. 性能优化:ArkTS针对鸿蒙系统进行了深度优化,提供了更好的运行时性能和更低的内存占耗,特别是在声明式UI框架ArkUI中表现出色。

  3. 类型安全增强:相比TypeScript,ArkTS进一步强化了类型系统,禁用了一些动态特性(如any类型的部分用法),提供更严格的类型检查,减少运行时错误。

  4. 生态整合:ArkTS与鸿蒙生态深度集成,提供了丰富的系统API和组件库,能够充分发挥鸿蒙系统的分布式能力和跨设备协同特性。

基础语法

程序入口

TypeScript:

TypeScript/JavaScript应用通常没有固定的程序入口,在Node.js环境中会从package.json指定的入口文件开始执行,在浏览器环境中则从HTML引入的脚本开始执行。

ArkTS:

ArkTS应用有明确的入口点,通常在entry/src/main/ets/entryability/EntryAbility.ets文件中

typescript 复制代码
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    console.info('Ability onCreate');
  }

  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.loadContent('pages/Index', (err, data) => {
      // 加载页面
    });
  }
}

页面入口通常在pages/Index.ets中:

typescript 复制代码
@Entry
@Component
struct Index {
  build() {
    // UI构建
  }
}

数据类型

基本类型

TypeScript与ArkTS共同支持的类型:

  • boolean: 布尔类型
  • number: 数字类型
  • string: 字符串类型
  • null: 空值
  • undefined: 未定义
  • bigint: 大整数(ES2020+)
  • symbol: 符号类型
typescript 复制代码
// TypeScript & ArkTS
let isDone: boolean = false;
let count: number = 10;
let name: string = "HarmonyOS";
let big: bigint = 100n;

Array(数组)

TypeScript:

typescript 复制代码
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];

ArkTS:

typescript 复制代码
// 推荐使用类型注解
let list1: number[] = [1, 2, 3];
let list2: Array<number> = [1, 2, 3];

// ArkTS中数组操作与TS基本一致
list1.push(4);
list1.forEach((item) => {
  console.log(item.toString());
});

Tuple(元组)

TypeScript:

typescript 复制代码
let tuple: [string, number] = ['hello', 10];

ArkTS:

typescript 复制代码
// ArkTS同样支持元组
let tuple: [string, number] = ['hello', 10];
let first: string = tuple[0];
let second: number = tuple[1];

Enum(枚举)

TypeScript:

typescript 复制代码
enum Color {
  Red,
  Green,
  Blue
}

enum Status {
  Success = 'SUCCESS',
  Fail = 'FAIL'
}

ArkTS:

typescript 复制代码
// ArkTS支持数字枚举和字符串枚举
enum Color {
  Red,
  Green,
  Blue
}

enum Status {
  Success = 'SUCCESS',
  Fail = 'FAIL'
}

let color: Color = Color.Red;

any 和 unknown

TypeScript:

typescript 复制代码
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;

let value: unknown = 4;
// unknown类型更安全,使用前需要类型检查
if (typeof value === 'string') {
  console.log(value.toUpperCase());
}

ArkTS:

typescript 复制代码
// ArkTS限制了any的使用,推荐使用具体类型
// 在某些场景下可以使用,但会有编译警告
let notSure: any = 4; // 不推荐

// 推荐使用联合类型替代
let value: string | number = 4;
value = "string";

Object(对象)

TypeScript:

typescript 复制代码
interface Person {
  name: string;
  age: number;
  email?: string; // 可选属性
}

let person: Person = {
  name: 'Zhang San',
  age: 25
};

ArkTS:

typescript 复制代码
// ArkTS中接口定义方式相同
interface Person {
  name: string;
  age: number;
  email?: string;
}

let person: Person = {
  name: 'Zhang San',
  age: 25
};

// 也可以使用class
class PersonClass {
  name: string;
  age: number;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

变量声明

let、const、var

TypeScript:

typescript 复制代码
var oldStyle = 'avoid using var'; // 不推荐
let mutableValue = 'can change';
const immutableValue = 'cannot change';

ArkTS:

typescript 复制代码
// ArkTS同样支持let和const,不推荐使用var
let mutableValue: string = 'can change';
const immutableValue: string = 'cannot change';

// ArkTS强制要求类型注解(在某些情况下)
let count: number = 0; // 推荐明确指定类型

类型推断

TypeScript:

typescript 复制代码
let message = "Hello"; // 推断为string类型
let count = 42; // 推断为number类型

ArkTS:

typescript 复制代码
// ArkTS支持类型推断,但更推荐显式声明
let message = "Hello"; // 可以推断
let count: number = 42; // 推荐显式声明

函数

函数声明

TypeScript:

typescript 复制代码
// 函数声明
function add(a: number, b: number): number {
  return a + b;
}

// 函数表达式
const multiply = function(a: number, b: number): number {
  return a * b;
};

// 箭头函数
const subtract = (a: number, b: number): number => {
  return a - b;
};

// 简写箭头函数
const divide = (a: number, b: number): number => a / b;

ArkTS:

typescript 复制代码
// ArkTS支持相同的函数声明方式
function add(a: number, b: number): number {
  return a + b;
}

const multiply = function(a: number, b: number): number {
  return a * b;
};

const subtract = (a: number, b: number): number => {
  return a - b;
};

const divide = (a: number, b: number): number => a / b;

可选参数和默认参数

TypeScript:

typescript 复制代码
function buildName(firstName: string, lastName?: string): string {
  if (lastName) {
    return firstName + " " + lastName;
  }
  return firstName;
}

function buildFullName(firstName: string, lastName: string = "Smith"): string {
  return firstName + " " + lastName;
}

ArkTS:

typescript 复制代码
// ArkTS中可选参数和默认参数用法相同
function buildName(firstName: string, lastName?: string): string {
  if (lastName) {
    return firstName + " " + lastName;
  }
  return firstName;
}

function buildFullName(firstName: string, lastName: string = "Smith"): string {
  return firstName + " " + lastName;
}

剩余参数

TypeScript:

typescript 复制代码
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

sum(1, 2, 3, 4); // 10

ArkTS:

typescript 复制代码
// ArkTS支持剩余参数
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

类

类的定义

TypeScript:

typescript 复制代码
class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hello, I'm ${this.name}`;
  }
}

const person = new Person("Zhang San", 25);

ArkTS:

typescript 复制代码
// ArkTS类定义方式相同
class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hello, I'm ${this.name}`;
  }
}

const person = new Person("Zhang San", 25);

访问修饰符

TypeScript:

typescript 复制代码
class Animal {
  public name: string;      // 公共属性
  private age: number;      // 私有属性
  protected type: string;   // 受保护属性

  constructor(name: string, age: number, type: string) {
    this.name = name;
    this.age = age;
    this.type = type;
  }

  public getAge(): number {
    return this.age;
  }
}

ArkTS:

typescript 复制代码
// ArkTS支持相同的访问修饰符
class Animal {
  public name: string;
  private age: number;
  protected type: string;

  constructor(name: string, age: number, type: string) {
    this.name = name;
    this.age = age;
    this.type = type;
  }

  public getAge(): number {
    return this.age;
  }
}

继承

TypeScript:

typescript 复制代码
class Animal {
  name: string;
  
  constructor(name: string) {
    this.name = name;
  }
  
  move(distance: number = 0): void {
    console.log(`${this.name} moved ${distance}m.`);
  }
}

class Dog extends Animal {
  bark(): void {
    console.log('Woof! Woof!');
  }
}

const dog = new Dog('Buddy');
dog.bark();
dog.move(10);

ArkTS:

typescript 复制代码
// ArkTS继承方式相同
class Animal {
  name: string;
  
  constructor(name: string) {
    this.name = name;
  }
  
  move(distance: number = 0): void {
    console.info(`${this.name} moved ${distance}m.`);
  }
}

class Dog extends Animal {
  bark(): void {
    console.info('Woof! Woof!');
  }
}

const dog = new Dog('Buddy');
dog.bark();
dog.move(10);

静态成员

TypeScript:

typescript 复制代码
class MathUtil {
  static PI: number = 3.14159;
  
  static calculateCircumference(radius: number): number {
    return 2 * MathUtil.PI * radius;
  }
}

console.log(MathUtil.PI);
console.log(MathUtil.calculateCircumference(10));

ArkTS:

typescript 复制代码
// ArkTS静态成员用法相同
class MathUtil {
  static PI: number = 3.14159;
  
  static calculateCircumference(radius: number): number {
    return 2 * MathUtil.PI * radius;
  }
}

console.info(MathUtil.PI.toString());
console.info(MathUtil.calculateCircumference(10).toString());

接口

接口定义

TypeScript:

typescript 复制代码
interface User {
  id: number;
  name: string;
  email?: string;
  readonly createdAt: Date;
}

interface Searchable {
  search(keyword: string): User[];
}

class UserService implements Searchable {
  search(keyword: string): User[] {
    // 实现搜索逻辑
    return [];
  }
}

ArkTS:

typescript 复制代码
// ArkTS接口定义方式相同
interface User {
  id: number;
  name: string;
  email?: string;
  readonly createdAt: Date;
}

interface Searchable {
  search(keyword: string): User[];
}

class UserService implements Searchable {
  search(keyword: string): User[] {
    return [];
  }
}

接口继承

TypeScript:

typescript 复制代码
interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

let square: Square = {
  color: "blue",
  sideLength: 10
};

ArkTS:

typescript 复制代码
// ArkTS接口继承方式相同
interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

let square: Square = {
  color: "blue",
  sideLength: 10
};

泛型

泛型函数

TypeScript:

typescript 复制代码
function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("hello");
let output2 = identity<number>(42);

ArkTS:

typescript 复制代码
// ArkTS支持泛型
function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("hello");
let output2 = identity<number>(42);

泛型类

TypeScript:

typescript 复制代码
class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

ArkTS:

typescript 复制代码
// ArkTS泛型类用法相同
class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型约束

TypeScript:

typescript 复制代码
interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

logLength({ length: 10, value: 3 });

ArkTS:

typescript 复制代码
// ArkTS泛型约束用法相同
interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): T {
  console.info(arg.length.toString());
  return arg;
}

异步编程

Promise

TypeScript:

typescript 复制代码
function fetchData(): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data loaded");
    }, 1000);
  });
}

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

ArkTS:

typescript 复制代码
// ArkTS支持Promise
function fetchData(): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data loaded");
    }, 1000);
  });
}

fetchData()
  .then(data => console.info(data))
  .catch(error => console.error(error));

async/await

TypeScript:

typescript 复制代码
async function loadUserData(userId: number): Promise<User> {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Failed to load user:', error);
    throw error;
  }
}

// 使用
async function main() {
  const user = await loadUserData(1);
  console.log(user);
}

ArkTS:

typescript 复制代码
// ArkTS支持async/await
import http from '@ohos.net.http';

async function loadUserData(userId: number): Promise<object> {
  try {
    let httpRequest = http.createHttp();
    const response = await httpRequest.request(`https://api.example.com/users/${userId}`);
    return JSON.parse(response.result.toString());
  } catch (error) {
    console.error('Failed to load user:', error);
    throw error;
  }
}

// 使用
async function main() {
  const user = await loadUserData(1);
  console.info(JSON.stringify(user));
}

模块系统

导出

TypeScript:

typescript 复制代码
// utils.ts
export function add(a: number, b: number): number {
  return a + b;
}

export class Calculator {
  multiply(a: number, b: number): number {
    return a * b;
  }
}

export default class MathUtil {
  static PI = 3.14159;
}

ArkTS:

typescript 复制代码
// utils.ets
export function add(a: number, b: number): number {
  return a + b;
}

export class Calculator {
  multiply(a: number, b: number): number {
    return a * b;
  }
}

// ArkTS也支持默认导出
export default class MathUtil {
  static PI = 3.14159;
}

导入

TypeScript:

typescript 复制代码
// 命名导入
import { add, Calculator } from './utils';

// 默认导入
import MathUtil from './utils';

// 导入所有
import * as Utils from './utils';

// 重命名导入
import { add as sum } from './utils';

ArkTS:

typescript 复制代码
// ArkTS导入方式相同
import { add, Calculator } from './utils';
import MathUtil from './utils';
import * as Utils from './utils';
import { add as sum } from './utils';

ArkTS独有特性(TypeScript没有的)

1. 声明式UI装饰器系统

这是ArkTS最重要的特性之一,TypeScript完全没有这套体系。

@Component - 自定义组件装饰器

ArkTS独有:

typescript 复制代码
// TypeScript中没有这种组件装饰器
@Component
struct CustomButton {
  private text: string = 'Click';
  
  build() {
    Button(this.text)
      .width(100)
      .height(40)
  }
}

@Entry - 页面入口装饰器

ArkTS独有:

typescript 复制代码
// 标记页面入口组件,TypeScript没有这个概念
@Entry
@Component
struct HomePage {
  build() {
    Column() {
      Text('Home Page')
    }
  }
}

@Preview - 预览装饰器

ArkTS独有:

typescript 复制代码
// 用于在DevEco Studio中预览组件,TypeScript没有
@Preview
@Component
struct PreviewComponent {
  build() {
    Text('Preview Mode')
      .fontSize(20)
  }
}

2. 状态管理装饰器

这是ArkTS最核心的特性,用于响应式UI开发,TypeScript完全没有。

@State - 组件内部状态

ArkTS独有:

typescript 复制代码
@Component
struct Counter {
  // @State装饰器使变量具有响应式能力
  // 当count变化时,UI会自动更新
  @State count: number = 0;
  
  build() {
    Column() {
      Text(`Count: ${this.count}`)
      Button('Increase')
        .onClick(() => {
          this.count++; // 修改会触发UI刷新
        })
    }
  }
}

TypeScript对比:

typescript 复制代码
// TypeScript需要手动管理状态更新
class Counter {
  private count: number = 0;
  
  increase() {
    this.count++;
    // 需要手动调用渲染函数
    this.render();
  }
  
  render() {
    // 手动更新DOM
  }
}

@Prop - 单向数据传递

ArkTS独有:

typescript 复制代码
@Component
struct ChildComponent {
  // @Prop从父组件接收数据,单向传递
  // 子组件不能修改@Prop装饰的变量
  @Prop message: string;
  
  build() {
    Text(this.message)
  }
}

@Entry
@Component
struct ParentComponent {
  @State parentMessage: string = 'Hello';
  
  build() {
    Column() {
      ChildComponent({ message: this.parentMessage })
      Button('Change')
        .onClick(() => {
          this.parentMessage = 'Hi'; // 子组件会自动更新
        })
    }
  }
}

ArkTS独有:

typescript 复制代码
@Component
struct ChildComponent {
  // @Link实现父子组件双向数据同步
  // 子组件可以修改,会同步到父组件
  @Link count: number;
  
  build() {
    Column() {
      Text(`Child: ${this.count}`)
      Button('Child +1')
        .onClick(() => {
          this.count++; // 修改会同步到父组件
        })
    }
  }
}

@Entry
@Component
struct ParentComponent {
  @State parentCount: number = 0;
  
  build() {
    Column() {
      Text(`Parent: ${this.parentCount}`)
      // 使用$符号传递引用
      ChildComponent({ count: $parentCount })
    }
  }
}

TypeScript对比:

typescript 复制代码
// TypeScript需要通过回调函数实现双向绑定
class ChildComponent {
  constructor(
    private count: number,
    private onChange: (value: number) => void
  ) {}
  
  increment() {
    this.count++;
    this.onChange(this.count); // 手动通知父组件
  }
}

@Provide 和 @Consume - 跨层级传递

ArkTS独有:

typescript 复制代码
// 祖先组件提供数据
@Entry
@Component
struct GrandParent {
  @Provide('theme') theme: string = 'dark';
  
  build() {
    Column() {
      Parent()
    }
  }
}

@Component
struct Parent {
  build() {
    Column() {
      Child()
    }
  }
}

// 后代组件消费数据,无需逐层传递
@Component
struct Child {
  @Consume('theme') theme: string;
  
  build() {
    Text(`Theme: ${this.theme}`)
      .fontColor(this.theme === 'dark' ? Color.White : Color.Black)
  }
}

TypeScript对比:

typescript 复制代码
// TypeScript需要使用Context或逐层传递props
// React示例
const ThemeContext = React.createContext('light');

function GrandParent() {
  return (
    <ThemeContext.Provider value="dark">
      <Parent />
    </ThemeContext.Provider>
  );
}

function Child() {
  const theme = useContext(ThemeContext);
  return <div>{theme}</div>;
}

ArkTS独有:

typescript 复制代码
// @Observed装饰类,使其实例具有响应式能力
@Observed
class Person {
  name: string;
  age: number;
  
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

@Component
struct PersonCard {
  // @ObjectLink用于嵌套对象的双向同步
  @ObjectLink person: Person;
  
  build() {
    Column() {
      Text(`Name: ${this.person.name}`)
      Text(`Age: ${this.person.age}`)
      Button('Birthday')
        .onClick(() => {
          this.person.age++; // 修改会触发UI更新
        })
    }
  }
}

@Entry
@Component
struct PersonList {
  @State people: Person[] = [
    new Person('Zhang San', 25),
    new Person('Li Si', 30)
  ];
  
  build() {
    Column() {
      ForEach(this.people, (person: Person) => {
        PersonCard({ person: person })
      })
    }
  }
}

@Watch - 状态监听

ArkTS独有:

typescript 复制代码
@Component
struct WatchExample {
  @State @Watch('onCountChange') count: number = 0;
  @State message: string = '';
  
  // 监听count变化
  onCountChange() {
    this.message = `Count changed to ${this.count}`;
    console.info(`Count is now: ${this.count}`);
  }
  
  build() {
    Column() {
      Text(this.message)
      Button('Increase')
        .onClick(() => {
          this.count++; // 会触发onCountChange
        })
    }
  }
}

3. 声明式UI构建语法

struct 结构体(用于UI组件)

ArkTS独有:

typescript 复制代码
// ArkTS使用struct定义UI组件
// TypeScript没有这种UI组件定义方式
@Component
struct MyComponent {
  build() {
    Column() {
      Text('Hello')
    }
  }
}

build() 方法

ArkTS独有:

typescript 复制代码
// build方法是ArkTS组件的核心
// 用于声明式地描述UI结构
@Component
struct UIExample {
  build() {
    // 链式调用设置属性
    Column() {
      Text('Title')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      
      Button('Click')
        .width(100)
        .onClick(() => {
          console.info('Clicked');
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

4. 内置UI组件

ArkTS提供了大量内置UI组件,TypeScript没有。

容器组件

ArkTS独有:

typescript 复制代码
@Entry
@Component
struct ContainerExample {
  build() {
    // Column - 垂直布局
    Column({ space: 10 }) {
      Text('Item 1')
      Text('Item 2')
    }
    
    // Row - 水平布局
    Row({ space: 20 }) {
      Text('Left')
      Text('Right')
    }
    
    // Stack - 层叠布局
    Stack() {
      Image($r('app.media.bg'))
      Text('Overlay Text')
    }
    
    // Flex - 弹性布局
    Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
      Text('Item 1').width('30%')
      Text('Item 2').width('30%')
      Text('Item 3').width('30%')
    }
    
    // Grid - 网格布局
    Grid() {
      GridItem() { Text('1') }
      GridItem() { Text('2') }
      GridItem() { Text('3') }
    }
    .columnsTemplate('1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr')
  }
}

基础组件

ArkTS独有:

typescript 复制代码
@Entry
@Component
struct BasicComponents {
  @State inputValue: string = '';
  @State isChecked: boolean = false;
  @State sliderValue: number = 50;
  
  build() {
    Column({ space: 15 }) {
      // Text组件
      Text('Hello HarmonyOS')
        .fontSize(24)
        .fontColor(Color.Blue)
        .fontWeight(FontWeight.Bold)
      
      // Button组件
      Button('Click Me')
        .type(ButtonType.Capsule)
        .width(200)
        .onClick(() => {
          console.info('Button clicked');
        })
      
      // Image组件
      Image($r('app.media.icon'))
        .width(100)
        .height(100)
        .borderRadius(50)
      
      // TextInput组件
      TextInput({ placeholder: 'Enter text' })
        .width('90%')
        .onChange((value: string) => {
          this.inputValue = value;
        })
      
      // Checkbox组件
      Checkbox()
        .select(this.isChecked)
        .onChange((value: boolean) => {
          this.isChecked = value;
        })
      
      // Slider组件
      Slider({
        value: this.sliderValue,
        min: 0,
        max: 100,
        step: 1
      })
        .width('90%')
        .onChange((value: number) => {
          this.sliderValue = value;
        })
      
      // Progress组件
      Progress({ value: this.sliderValue, total: 100 })
        .width('90%')
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

5. 条件渲染和循环渲染

if/else 条件渲染

ArkTS独有:

typescript 复制代码
@Component
struct ConditionalRender {
  @State isLoggedIn: boolean = false;
  @State userType: string = 'guest';
  
  build() {
    Column() {
      // if条件渲染
      if (this.isLoggedIn) {
        Text('Welcome back!')
          .fontSize(20)
      } else {
        Text('Please login')
          .fontSize(16)
      }
      
      // if-else if-else
      if (this.userType === 'admin') {
        Button('Admin Panel')
      } else if (this.userType === 'user') {
        Button('User Dashboard')
      } else {
        Button('Guest Mode')
      }
      
      // 三元表达式
      Text(this.isLoggedIn ? 'Online' : 'Offline')
        .fontColor(this.isLoggedIn ? Color.Green : Color.Gray)
    }
  }
}

ForEach 循环渲染

ArkTS独有:

typescript 复制代码
@Entry
@Component
struct ListExample {
  @State items: string[] = ['Apple', 'Banana', 'Orange', 'Grape'];
  
  build() {
    Column() {
      // ForEach循环渲染
      ForEach(
        this.items,                    // 数据源
        (item: string, index: number) => {  // 渲染函数
          Row() {
            Text(`${index + 1}. ${item}`)
              .fontSize(18)
          }
          .width('100%')
          .height(50)
          .padding(10)
        },
        (item: string) => item         // 键生成函数(可选)
      )
    }
  }
}

LazyForEach 懒加载列表

ArkTS独有:

typescript 复制代码
// 实现IDataSource接口
class MyDataSource implements IDataSource {
  private list: string[] = [];
  
  constructor(list: string[]) {
    this.list = list;
  }
  
  totalCount(): number {
    return this.list.length;
  }
  
  getData(index: number): string {
    return this.list[index];
  }
  
  registerDataChangeListener(listener: DataChangeListener): void {
    // 注册监听器
  }
  
  unregisterDataChangeListener(listener: DataChangeListener): void {
    // 注销监听器
  }
}

@Entry
@Component
struct LazyListExample {
  private data: MyDataSource = new MyDataSource(
    Array.from({ length: 1000 }, (_, i) => `Item ${i}`)
  );
  
  build() {
    List() {
      // LazyForEach实现懒加载,只渲染可见区域
      LazyForEach(
        this.data,
        (item: string) => {
          ListItem() {
            Text(item)
              .width('100%')
              .height(50)
          }
        },
        (item: string) => item
      )
    }
    .width('100%')
    .height('100%')
  }
}

6. @Builder 自定义构建函数

ArkTS独有:

typescript 复制代码
@Component
struct BuilderExample {
  @State count: number = 0;
  
  // @Builder装饰的函数可以复用UI结构
  @Builder CustomButton(text: string, action: () => void) {
    Button(text)
      .width(150)
      .height(40)
      .onClick(action)
  }
  
  // 全局@Builder(在struct外部)
  @Builder
  function GlobalHeader(title: string) {
    Row() {
      Text(title)
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
    }
    .width('100%')
    .height(60)
    .backgroundColor('#f0f0f0')
  }
  
  build() {
    Column({ space: 20 }) {
      GlobalHeader('My Page')
      
      Text(`Count: ${this.count}`)
      
      // 复用自定义构建函数
      this.CustomButton('Increase', () => {
        this.count++;
      })
      
      this.CustomButton('Decrease', () => {
        this.count--;
      })
      
      this.CustomButton('Reset', () => {
        this.count = 0;
      })
    }
  }
}

7. @Styles 样式复用

ArkTS独有:

typescript 复制代码
// 全局@Styles
@Styles function globalFancyText() {
  .fontSize(20)
  .fontColor(Color.Blue)
  .fontWeight(FontWeight.Bold)
}

@Component
struct StylesExample {
  // 组件内@Styles
  @Styles fancyButton() {
    .width(200)
    .height(50)
    .backgroundColor(Color.Orange)
    .borderRadius(25)
  }
  
  build() {
    Column({ space: 20 }) {
      // 使用全局样式
      Text('Global Style')
        .globalFancyText()
      
      // 使用组件样式
      Button('Fancy Button')
        .fancyButton()
      
      Button('Another Fancy Button')
        .fancyButton()
    }
  }
}

8. @Extend 扩展组件样式

ArkTS独有:

typescript 复制代码
// @Extend只能用于扩展内置组件
@Extend(Text) function fancyText(fontSize: number, color: Color) {
  .fontSize(fontSize)
  .fontColor(color)
  .fontWeight(FontWeight.Bold)
  .textAlign(TextAlign.Center)
  .padding(10)
  .backgroundColor('#f5f5f5')
  .borderRadius(8)
}

@Extend(Button) function primaryButton() {
  .width(200)
  .height(50)
  .backgroundColor(Color.Blue)
  .fontColor(Color.White)
  .borderRadius(25)
}

@Entry
@Component
struct ExtendExample {
  build() {
    Column({ space: 20 }) {
      // 使用扩展样式
      Text('Extended Text')
        .fancyText(18, Color.Red)
      
      Text('Another Text')
        .fancyText(16, Color.Green)
      
      Button('Primary Action')
        .primaryButton()
    }
  }
}

9. @CustomDialog 自定义弹窗

ArkTS独有:

typescript 复制代码
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController;
  title: string = 'Dialog Title';
  message: string = 'Dialog message';
  confirm: () => void;
  
  build() {
    Column({ space: 20 }) {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      
      Text(this.message)
        .fontSize(16)
      
      Row({ space: 20 }) {
        Button('Cancel')
          .onClick(() => {
            this.controller.close();
          })
        
        Button('Confirm')
          .onClick(() => {
            this.confirm();
            this.controller.close();
          })
      }
    }
    .padding(20)
  }
}

@Entry
@Component
struct DialogPage {
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({
      title: 'Delete Confirmation',
      message: 'Are you sure you want to delete this item?',
      confirm: () => {
        console.info('Item deleted');
      }
    }),
    autoCancel: true
  });
  
  build() {
    Column() {
      Button('Show Dialog')
        .onClick(() => {
          this.dialogController.open();
        })
    }
  }
}

10. @AnimatableExtend 可动画属性扩展

ArkTS独有:

typescript 复制代码
@AnimatableExtend(Text) function animatableFontSize(size: number) {
  .fontSize(size)
}

@Entry
@Component
struct AnimationExample {
  @State fontSize: number = 20;
  
  build() {
    Column({ space: 20 }) {
      Text('Animated Text')
        .animatableFontSize(this.fontSize)
        .animation({
          duration: 500,
          curve: Curve.EaseInOut
        })
      
      Button('Increase Font')
        .onClick(() => {
          this.fontSize += 5;
        })
      
      Button('Decrease Font')
        .onClick(() => {
          this.fontSize -= 5;
        })
    }
  }
}

11. @Concurrent 并发装饰器

ArkTS独有:

typescript 复制代码
// @Concurrent用于标记可以并发执行的函数
@Concurrent
function heavyComputation(data: number[]): number {
  // 耗时计算
  let sum = 0;
  for (let i = 0; i < data.length; i++) {
    sum += data[i] * data[i];
  }
  return sum;
}

@Entry
@Component
struct ConcurrentExample {
  @State result: number = 0;
  @State loading: boolean = false;
  
  async performHeavyTask() {
    this.loading = true;
    const data = Array.from({ length: 1000000 }, (_, i) => i);
    
    try {
      // 在子线程中执行
      this.result = await taskpool.execute(heavyComputation, data);
    } catch (error) {
      console.error('Task failed:', error);
    } finally {
      this.loading = false;
    }
  }
  
  build() {
    Column({ space: 20 }) {
      if (this.loading) {
        LoadingProgress()
      } else {
        Text(`Result: ${this.result}`)
      }
      
      Button('Start Heavy Task')
        .onClick(() => {
          this.performHeavyTask();
        })
    }
  }
}

12. @Reusable 组件复用

ArkTS独有:

typescript 复制代码
// @Reusable标记可复用组件,提升性能
@Reusable
@Component
struct ReusableListItem {
  @State item: string = '';
  
  // 组件即将被复用时调用
  aboutToReuse(params: Record<string, Object>) {
    this.item = params.item as string;
  }
  
  build() {
    Row() {
      Text(this.item)
        .fontSize(16)
    }
    .width('100%')
    .height(50)
    .padding(10)
  }
}

@Entry
@Component
struct ReusableListExample {
  @State items: string[] = Array.from({ length: 100 }, (_, i) => `Item ${i}`);
  
  build() {
    List() {
      ForEach(this.items, (item: string) => {
        ListItem() {
          ReusableListItem({ item: item })
        }
      })
    }
  }
}

13. 资源引用系统

ArkTS独有:

typescript 复制代码
@Entry
@Component
struct ResourceExample {
  build() {
    Column({ space: 20 }) {
      // $r引用资源文件
      Text($r('app.string.hello'))  // 引用字符串资源
        .fontSize($r('app.float.title_font_size'))  // 引用数值资源
        .fontColor($r('app.color.primary'))  // 引用颜色资源
      
      Image($r('app.media.icon'))  // 引用图片资源
        .width(100)
        .height(100)
      
      // $rawfile引用rawfile目录下的文件
      Image($rawfile('background.png'))
      
      // 使用资源的格式化字符串
      Text($r('app.string.welcome_message', 'Zhang San'))
    }
  }
}

14. LocalStorage 页面级状态管理

ArkTS独有:

typescript 复制代码
// 创建LocalStorage实例
let storage = new LocalStorage({ 'count': 0 });

@Entry(storage)
@Component
struct PageA {
  // @LocalStorageLink双向绑定
  @LocalStorageLink('count') count: number = 0;
  
  build() {
    Column({ space: 20 }) {
      Text(`Count: ${this.count}`)
      
      Button('Increase')
        .onClick(() => {
          this.count++;
        })
      
      Button('Go to Page B')
        .onClick(() => {
          router.pushUrl({ url: 'pages/PageB' });
        })
    }
  }
}

@Entry(storage)
@Component
struct PageB {
  // @LocalStorageProp单向同步
  @LocalStorageProp('count') count: number = 0;
  
  build() {
    Column() {
      Text(`Count from Page A: ${this.count}`)
    }
  }
}

15. AppStorage 应用级状态管理

ArkTS独有:

typescript 复制代码
// 初始化应用全局状态
AppStorage.SetOrCreate('userInfo', { name: 'Guest', isLoggedIn: false });
AppStorage.SetOrCreate('theme', 'light');

@Entry
@Component
struct HomePage {
  // @StorageLink双向绑定应用全局状态
  @StorageLink('userInfo') userInfo: object = {};
  @StorageLink('theme') theme: string = 'light';
  
  build() {
    Column() {
      Text(`User: ${this.userInfo['name']}`)
      Text(`Theme: ${this.theme}`)
      
      Button('Toggle Theme')
        .onClick(() => {
          this.theme = this.theme === 'light' ? 'dark' : 'light';
        })
    }
  }
}

@Component
struct SettingsPage {
  // @StorageProp单向同步
  @StorageProp('theme') theme: string = 'light';
  
  build() {
    Column() {
      Text(`Current Theme: ${this.theme}`)
    }
  }
}

16. PersistentStorage 持久化存储

ArkTS独有:

typescript 复制代码
// 持久化存储,应用重启后数据仍然存在
PersistentStorage.PersistProp('token', '');
PersistentStorage.PersistProp('username', 'Guest');

@Entry
@Component
struct LoginPage {
  @StorageLink('token') token: string = '';
  @StorageLink('username') username: string = '';
  
  login(username: string, password: string) {
    // 登录逻辑
    this.token = 'generated_token';
    this.username = username;
    // 数据会自动持久化
  }
  
  build() {
    Column() {
      if (this.token) {
        Text(`Welcome, ${this.username}`)
      } else {
        Button('Login')
          .onClick(() => {
            this.login('user123', 'password');
          })
      }
    }
  }
}

17. Environment 环境变量

ArkTS独有:

typescript 复制代码
// 监听系统环境变化
Environment.EnvProp('colorMode', ColorMode.LIGHT);
Environment.EnvProp('languageCode', 'zh');

@Entry
@Component
struct EnvironmentExample {
  @StorageProp('colorMode') colorMode: number = ColorMode.LIGHT;
  @StorageProp('languageCode') language: string = 'zh';
  
  build() {
    Column() {
      Text(`Color Mode: ${this.colorMode === ColorMode.LIGHT ? 'Light' : 'Dark'}`)
      Text(`Language: ${this.language}`)
    }
    .backgroundColor(this.colorMode === ColorMode.LIGHT ? Color.White : Color.Black)
  }
}

ArkTS与TypeScript的主要区别总结

TypeScript没有但ArkTS有的核心特性:

  1. 声明式UI装饰器系统

    • @Component、@Entry、@Preview 等组件装饰器
    • TypeScript完全没有UI组件的概念
  2. 响应式状态管理装饰器

    • @State、@Prop、@Link、@Provide、@Consume
    • @ObjectLink、@Observed、@Watch
    • TypeScript需要借助第三方库(如MobX、Redux)
  3. UI构建专用语法

    • struct 结构体定义组件
    • build() 方法声明式构建UI
    • 链式调用设置属性
    • TypeScript没有这种内置UI语法
  4. 内置UI组件库

    • Column、Row、Stack、Flex、Grid等容器组件
    • Text、Button、Image、TextInput等基础组件
    • TypeScript需要依赖第三方UI框架
  5. UI复用装饰器

    • @Builder 自定义构建函数
    • @Styles 样式复用
    • @Extend 扩展组件
    • @CustomDialog 自定义弹窗
    • TypeScript没有这些UI复用机制
  6. 条件和循环渲染

    • ForEach、LazyForEach 专用循环语法
    • 在build方法中直接使用if/else
    • TypeScript需要使用JSX或模板语法
  7. 状态管理系统

    • LocalStorage 页面级状态
    • AppStorage 应用级状态
    • PersistentStorage 持久化存储
    • Environment 环境变量
    • TypeScript需要第三方状态管理库
  8. 资源管理系统

    • $r() 资源引用
    • $rawfile() 原始文件引用
    • TypeScript没有统一的资源管理系统
  9. 并发和性能优化

    • @Concurrent 并发装饰器
    • @Reusable 组件复用
    • @AnimatableExtend 动画扩展
    • TypeScript需要手动管理
  10. 鸿蒙特有API

    • 分布式能力API
    • 系统服务API
    • 设备协同API

ArkTS限制的TypeScript特性:

  1. 禁用或限制的特性

    • 严格限制any类型使用
    • 禁止原型链操作
    • 禁止eval和Function构造器
    • 禁止with语句
    • 限制动态属性访问
  2. 更严格的类型要求

    • 强制类型声明
    • 更严格的null安全检查
    • 更严格的类型推断

总结: ArkTS在TypeScript基础上,新增了完整的声明式UI开发体系、响应式状态管理系统、内置组件库等大量TypeScript没有的特性,同时限制了一些动态特性以提高性能和类型安全。这使得ArkTS成为专门为鸿蒙应用开发设计的语言。

相关推荐
jay神35 分钟前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神43 分钟前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat1 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan2 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真2 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment2 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan2 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技3 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue