harmony-arkts について
ArkTS と ArkUI で HarmonyOS アプリを開発する人向けのスキルです。コンポーネント構成、状態管理、レイアウト、ライフサイクル、リソース、アクセシビリティの指針を提供します。
主な機能
- 01ArkTS コンポーネント構成の指針
- 02状態とデータフローの管理
- 03ArkUI レイアウトとスタイルの助言
- 04ライフサイクルとイベント処理
- 05リソース参照とアクセシビリティ確認
活用シーン
- 01保守しやすい ArkTS コンポーネントの設計
- 02コンポーネントの状態バインディング選択
- 03UI レイアウトとイベント処理の確認
- 04アクセシビリティとデバイス適応の改善
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill harmony-arktsインストール後、Claude Code で/harmony-arktsを入力して読み込まれたか確認します。
詳細
HarmonyOS ArkTS 開発
このスキルでは、ArkTS と宣言型 ArkUI フレームワークを使用した HarmonyOS アプリケーションの構築について、コンポーネント構造、状態管理、レイアウト、ライフサイクル、リソース、アクセシビリティを含めて説明します。
ArkTS コンポーネントを構築するワークフロー
- コンポーネントを定義する —
@Componentを付けたstructを作成し、名前をパスカルケースにします。 - 状態を上部に宣言する — メソッドより前に、
@State、@Prop、@Linkなどの状態デコレーターを記述します。 - ライフサイクルフックを追加する — 状態宣言の後、
build()の前に、必要に応じてaboutToAppear()/aboutToDisappear()などを実装します。 - build() で UI を構成する —
Column、Row、Stack、Listなどの ArkUI プリミティブを使用して子コンポーネントを配置し、build()に記述します。 - 複雑な UI を切り出す —
build()が大きくなったり、ネストが深くなったりしたら、各セクションを小さな@Componentのstructまたは@Builder関数に切り出します。 - イベントを接続する — アロー関数のイベントハンドラーを設定し、複雑なロジックはコンポーネントの名前付きメソッドに委譲します。
- リソースを外部化する — 文字列、色、寸法、画像をリソースシステムに移し、
$r()で参照します。 - アクセシビリティとレスポンシブ対応を確認する — アクセシビリティラベルを追加し、タッチターゲットのサイズを確認して、代表的なデバイスサイズや画面の向きでテストします。
コンポーネント構造
@Componentを使用してコンポーネントを定義し、コンポーネントのstruct名にはパスカルケースを使用します(例:struct UserProfileCard)。- 状態宣言(
@State、@Prop、@Link、@StorageLink、通常のフィールド)は、メソッドやライフサイクルフックより前のコンポーネント上部にまとめます。 - ライフサイクルフック(
aboutToAppear、aboutToDisappear、onPageShow、onPageHide)はbuild()より前に配置し、コンポーネントのライフサイクルを確認しやすくします。 build()は最後に配置し、UI の構成だけに専念させます。データ変換やビジネスロジックはbuild()内に直接記述せず、build()から呼び出すメソッドに切り出します。build()メソッドが画面 1 枚分を超えるほど長くなったり、数階層以上ネストしたりしたら、複雑な UI を小さな@Componentのstruct(軽量で再利用可能な UI の断片には@Builder関数)に切り出します。
状態とデータフロー
- コンポーネント自身が所有し、変更する状態には
@Stateを使用します。 - 親から子への一方向のデータ受け渡しには
@Propを使用します。子は独自のコピーを受け取り、子側の変更は親に反映されません。 @Linkは、子が親の状態を変更する必要が本当にある場合(カスタムフォームコントロールなど)に限り、意図的な双方向バインディングに使用します。- 派生値を重複して保持し、手動で同期するのではなく、計算用のヘルパーメソッドで求めます(
itemCountがthis.items.lengthで取得できる場合、itemsとitemCountを別々の@Stateフィールドとして保存しないでください)。 - プロジェクトに確立されたアプリ状態のパターンがない限り、広範なグローバル状態(無差別な
AppStorage/LocalStorageの使用)は避けます。真にグローバルなデータでない限り、プロパティやリンクを通じてデータを渡す方法を優先します。
例:状態、プロパティ、ライフサイクルを備えたコンポーネント
@Component
export struct CounterCard {
@Prop label: string = 'Counter';
@State private count: number = 0;
private maxCount: number = 99;
aboutToAppear(): void {
console.info(`CounterCard mounted with label=${this.label}`);
}
private increment = (): void => {
if (this.count >= this.maxCount) {
return;
}
this.count += 1;
};
private reset = (): void => {
this.count = 0;
};
build() {
Column({ space: 12 }) {
Text(this.label)
.fontSize(18)
.fontWeight(FontWeight.Medium)
Text(`${this.count}`)
.fontSize(32)
.fontColor($r('app.color.primary'))
.accessibilityText(`Current count is ${this.count}`)
Row({ space: 8 }) {
Button('Increment')
.onClick(this.increment)
.accessibilityText('Increment counter')
Button('Reset')
.onClick(this.reset)
.accessibilityText('Reset counter')
}
}
.width('100%')
.padding(16)
.alignItems(HorizontalAlign.Center)
}
}
レイアウトとスタイル
- 必要な軸や重なり方に応じて、
Column、Row、Stack、Listなどの ArkUI レイアウトプリミティブを意図的に使います。Stackをデフォルトで使い、すべてを絶対配置にするのは避けてください。 - 幅、高さ、配置、レイアウトウェイト(
layoutWeight)などのレイアウトプロパティは、色、フォント、枠線などの見た目のプロパティより前に、修飾子のチェーン内でまとめて指定します。これにより、装飾より先に構造を読み取れます。 - 各辺の余白が異なる場合は、単一の省略記法で均等な余白を示すのではなく、オブジェクト形式でマージンとパディングを指定します(
.margin({ top: 8, bottom: 16, left: 12, right: 12 }))。 - デバイスのピクセル密度に応じてレイアウトを正しく拡大・縮小できるよう、サイズには一貫して論理ピクセル(
vp)を使い、ピクセル値を混在させないでください。 - 固定値をハードコードするのではなく、親コンテナに対する相対サイズにはパーセント文字列(
'100%'、'50%')を使います。 - プロジェクトがリソースシステムをサポートしている場合は、再利用する余白、色、タイポグラフィの値をリソースシステム(
$r('app.color.primary')、$r('app.float.spacing_md'))にまとめ、コンポーネント間でリテラル値を繰り返さないようにします。
イベントとライフサイクル
- イベントハンドラーにはアロー関数(
.onClick(() => this.handleTap()))か、バインド済みのクラスフィールド(private handleTap = () => {...})を使い、余計な定型コードなしでthisが正しくバインドされるようにします。 - イベントハンドラー自体は短く保ちます。イベントを読み取ったら、テストや推論がしやすい名前付きメソッドに、複雑な処理を委譲します。
- 非同期処理の失敗は明示的に処理します(
awaitをtry/catchで囲みます)。拒否されたプロミスを黙って消失させず、トーストやインラインのエラー状態などでユーザーにエラーを伝えます。 - ライフサイクルフック(
aboutToAppear、aboutToDisappear、onPageShow、onPageHide、onBackPress)は、コンポーネントやページのライフサイクルに本当に依存するセットアップや後処理に限って使います。通常のメソッドに置けるロジックの受け皿にしないでください。
リソースとアクセシビリティ
- コンポーネントコードに値を直接埋め込むのではなく、アプリのリソース(文字列、色、メディア、浮動小数点値)の参照には
$r()を使います。 - リソース参照を一貫した形でグループ化し、アプリの成長に合わせて見つけやすいよう、
resources/base/element/string.json、color.json、float.jsonを機能や画面ごとに整理します。 - すべてのインタラクティブ要素に、説明的なアクセシビリティラベル(
.accessibilityText()、.accessibilityDescription())と適切なフォーカス処理(.focusable(true)、.tabIndex())を追加します。 - テキストと背景の間に十分な色のコントラストを確保し、タップ可能な要素のタッチ領域は、プラットフォームが推奨する最小サイズ(通常は 40vp 以上)を維持します。
- 代表的なデバイスのサイズや向き(スマートフォン、折りたたみ式端末、タブレット、横向き/縦向き)でテストします。あるフォームファクターでは正しく見える ArkUI レイアウトも、別のフォームファクターでは崩れることがあります。
よくある間違い
- データ取得、検証、複雑な分岐などのビジネスロジックを専用メソッドに分けず、
build()内に直接埋め込むこと。build()はプログラムではなく、UI ツリーとして読めるようにします。 - 単純な一方向の
@Propで十分な場合に、双方向バインディングの@Linkを使うこと。これにより、データフローの追跡が難しくなり、子コンポーネントから意図せず変更されるおそれも高まります。 - リソースシステムで管理すべき文字列、色、サイズを繰り返しハードコードすること。これにより、ローカライズやテーマの変更時にコンポーネントコードを探し回ることになります。
- 本番コードの実行経路にデバッグ用の
console.log/console.info呼び出しを残すこと。ログにノイズが増え、内部状態が漏れるおそれがあります。
コメント
Markdown 対応