对照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. 条件和循环渲染

    • ForEachLazyForEach 专用循环语法
    • 在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类型使用
    • 禁止原型链操作
    • 禁止evalFunction构造器
    • 禁止with语句
    • 限制动态属性访问
  2. 更严格的类型要求

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

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

相关推荐
奋斗猿1 小时前
前端实测:RSC不是银弹,但它真的重构了我的技术栈
前端·react.js
Hilaku1 小时前
为什么永远不要相信前端输入?绕过前端验证,只需一个 cURL 命令!
前端·javascript·安全
玄魂1 小时前
VChart 扩展新功能:一行代码解锁数据回归与趋势分析
前端·echarts·数据可视化
AndyGoWei2 小时前
pnpm 是什么,看这篇文章就够了
前端·javascript
zl0_00_02 小时前
isctf2025 部分wp
linux·前端·javascript
西洼工作室2 小时前
移动开发常见问题
前端·css3·web移动开发
同学807962 小时前
新版本Chrome谷歌浏览器访问本地网络请求跨域无法正常请求
前端·http
儿歌八万首2 小时前
Jetpack Compose 实战:打造高性能轮播图 (Carousel) 组件
android·前端·kotlin
m0_616188492 小时前
循环多个表单进行表单校验
前端·vue.js·elementui