跳转至

HarmonyOS / ArkTS 模式

本文件使用 HarmonyOS 和 ArkTS 特有的模式扩展 common/patterns.md。

状态管理:仅 V2

ArkUI 状态管理 V2 必须使用。V1 装饰器已弃用,不得使用。

V2 装饰器

装饰器 用途
@ComponentV2 将结构体标记为 V2 组件
@Local 组件内的本地状态
@Param 从父组件接收的属性(只读)
@Event 从子组件到父组件的回调事件
@Provider 向后代组件提供状态
@Consumer 从祖先的 @Provider 获取状态
@Monitor 监视状态变化(替代 V1 的 @Watch)
@Computed 派生/计算值
@ObservedV2 使类可观察以用于 V2 状态管理
@Trace 标记 @ObservedV2 类的可观察属性

禁止的 V1 装饰器

绝对不要使用:@State、@Prop、@Link、@ObjectLink、@Observed、@Provide、@Consume、@Watch、@Component(请改用 @ComponentV2)。

V2 组件示例

@ObservedV2
class UserModel {
  @Trace name: string = ''
  @Trace age: number = 0
}

@ComponentV2
struct UserCard {
  @Param user: UserModel = new UserModel()
  @Event onDelete: () => void = () => {}

  build() {
    Column() {
      Text(this.user.name)
        .fontSize($r('app.float.font_size_title'))
      Text(`${this.user.age}`)
        .fontSize($r('app.float.font_size_body'))
      Button($r('app.string.delete'))
        .onClick(() => this.onDelete())
    }
  }
}

状态同步

@ComponentV2
struct ParentPage {
  @Provider('userState') userModel: UserModel = new UserModel()

  build() {
    Column() {
      ChildComponent()  // @Consumer('userState') を自動的に受け取る
    }
  }
}

@ComponentV2
struct ChildComponent {
  @Consumer('userState') userModel: UserModel = new UserModel()

  build() {
    Text(this.userModel.name)
  }
}

路由:仅 Navigation

必须使用使用 NavPathStack 的 Navigation 组件。绝对不要使用 @ohos.router。

@ComponentV2
struct MainPage {
  @Local navPathStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.navPathStack) {
      // ホームコンテンツ
    }
    .navDestination(this.routerMap)
  }

  @Builder
  routerMap(name: string, param: ESObject) {
    if (name === 'detail') {
      DetailPage()
    } else if (name === 'settings') {
      SettingsPage()
    }
  }
}
// 新しいページをプッシュする
this.navPathStack.pushPath({ name: 'detail', param: { id: '123' } })

// 現在のページを置き換える
this.navPathStack.replacePath({ name: 'settings' })

// 戻る
this.navPathStack.pop()

// ルートに戻る
this.navPathStack.clear()
@ComponentV2
struct DetailPage {
  build() {
    NavDestination() {
      Column() {
        Text($r('app.string.detail_title'))
      }
    }
    .title($r('app.string.detail_nav_title'))
  }
}

架构模式:MVVM

HarmonyOS 应用推荐的架构:

feature/
  |-- model/           # データモデル(@ObservedV2 クラス)
  |-- viewmodel/       # ビジネスロジック(ViewModel クラス)
  |-- view/            # UI コンポーネント(@ComponentV2 構造体)
  |-- service/         # API 呼び出し、データアクセス
  • View:仅包含渲染逻辑,不要在 build() 中包含业务逻辑
  • ViewModel:将所有业务逻辑封装在这里
  • Model:带有 @ObservedV2 和 @Trace 的纯数据类
  • Service:网络请求、数据库操作、文件 I/O

ArkUI 动画模式

状态驱动动画

@ComponentV2
struct AnimatedCard {
  @Local isExpanded: boolean = false
  @Local cardScale: number = 0.8

  build() {
    Column() {
      // コンテンツ
    }
    .scale({ x: this.cardScale, y: this.cardScale })
    .animation({ duration: 300, curve: Curve.EaseInOut })
    .onClick(() => {
      this.isExpanded = !this.isExpanded
      this.cardScale = this.isExpanded ? 1.0 : 0.8
    })
  }
}

动画规则

  • 优先使用原生 HarmonyOS 动画 API 和高级模板
  • 使用声明式 UI,通过状态变量变更触发状态驱动动画
  • 设置 renderGroup(true) 以减少复杂子组件动画的渲染批次
  • 动画期间不要频繁修改 width、height、padding、margin — 会对性能造成严重影响
  • 显式动画控制使用 animateTo
  • 高性能动画优先使用 transform(translate、scale、rotate)和 opacity

性能模式

大列表使用 LazyForEach

@ComponentV2
struct LargeList {
  @Local dataSource: MyDataSource = new MyDataSource()

  build() {
    List() {
      LazyForEach(this.dataSource, (item: ItemModel) => {
        ListItem() {
          ItemComponent({ item: item })
        }
      }, (item: ItemModel) => item.id)
    }
  }
}

组件复用

  • 将可复用组件提取到单独文件中
  • 组件内的轻量级 UI 片段使用 @Builder
  • 可配置组件使用 @Param

资源引用

UI 常量应始终定义为资源,并通过 $r() 引用:

// BAD: ハードコードされた値
Text('Hello')
  .fontSize(16)
  .fontColor('#333333')

// GOOD: リソース参照
Text($r('app.string.greeting'))
  .fontSize($r('app.float.font_size_body'))
  .fontColor($r('app.color.text_primary'))

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC