ArkTS はレンダリング制御機能を提供します。条件付きレンダリングでは、if、else、else if を使用して、アプリケーションのさまざまな状態に応じて、対応する状態で UI コンテンツをレンダリングできます。注: API バージョン 9 以降、このインターフェイスは ArkTS カードでの使用をサポートします。
1. 使用規則
if、else、else if 文をサポートします。
if および else if に続く条件文では状態変数を使用できます。
コンテナ コンポーネント内で使用して、条件付きレンダリング ステートメントを通じてさまざまなサブコンポーネントを構築できるようにします。
条件付きレンダリング ステートメントは、コンポーネントの親子関係に関しては「透過的」です。親コンポーネントと子コンポーネントの間に 1 つ以上の if ステートメントが存在する場合、子コンポーネントの使用に関する親コンポーネントのルールは次のとおりである必要があります。続いて。
各ブランチ内のビルド関数は、ビルド関数のルールに従って、1 つ以上のコンポーネントを作成する必要があります。コンポーネントを作成できない空のコンストラクターでは、構文エラーが発生します。
一部のコンテナ コンポーネントでは、子コンポーネントのタイプまたは数が制限されています。これらのコンポーネント内で条件付きレンダリング ステートメントが使用されている場合、これらの制限は、条件付きレンダリング ステートメント内で作成されたコンポーネントにも適用されます。たとえば、Grid コンテナ コンポーネントのサブコンポーネントは GridItem コンポーネントのみをサポートします。グリッド内で条件付きレンダリング ステートメントを使用する場合、条件付きレンダリング ステートメント内では GridItem コンポーネントのみが許可されます。
2. 更新の仕組み
if、else if以降の状態判定で使用する状態変数の値が変化した場合、条件描画文を更新します 更新手順は以下のとおりです。
ブランチが変更されない場合は、以下の手順を実行する必要はありません。ブランチに変更がある場合は、手順 2 と 3 を実行します。
2. 以前に構築されたすべてのサブコンポーネントを削除します。
3. 新しいブランチのコンストラクターを実行し、取得したコンポーネントを if 親コンテナーに追加します。該当する else ブランチがない場合は、何も構築されません。
条件には Typescript 式を含めることができます。コンストラクター内の式の場合、そのような式はアプリケーションの状態を変更してはなりません。
3. 使用シナリオ
1. 条件付きレンダリングに if を使用する
@Entry
@Component
struct ViewA {
@State count: number = 0;
build() {
Column() {
Text(`count=${this.count}`)
if (this.count > 0) {
Text(`count is positive`)
.fontColor(Color.Green)
}
Button('increase count')
.onClick(() => {
this.count++;
})
Button('decrease count')
.onClick(() => {
this.count--;
})
}
}
}
if ステートメントの各分岐にはコンストラクター関数が含まれています。このようなコンストラクターは 1 つ以上のサブコンポーネントを作成する必要があります。最初のレンダリング時に、if ステートメントは build 関数を実行し、結果の子コンポーネントをその親コンポーネントに追加します。
if または else if 条件文で使用される状態変数が変更されるたびに、条件文は更新され、新しい条件値が再評価されます。条件値の評価が変化した場合、これは別の条件分岐を構築する必要があることを意味します。この時点で、ArkUI フレームワークは次の処理を実行します。
1. 以前にレンダリングされた (初期ブランチ) コンポーネントをすべて削除します。
2. 新しいブランチのコンストラクターを実行し、生成されたサブコンポーネントをその親コンポーネントに追加します。
上記の例では、count が 0 から 1 に増加すると、if ステートメントが更新され、条件 count > 0 が再評価され、評価結果が false から true に変わります。したがって、true ブランチのコンストラクターが実行され、Text コンポーネントが作成され、親コンポーネントの Column に追加されます。その後のカウントが 0 に変化すると、Text コンポーネントが Column コンポーネントから削除されます。else 分岐がないため、新しいコンストラクターは実行されません。
2.if…else…ステートメントとサブコンポーネントの状態
次の例には、@State 修飾された変数を持つ if…else…ステートメントとサブコンポーネントが含まれています。
@Component
struct CounterView {
@State counter: number = 0;
label: string = 'unknown';
build() {
Row() {
Text(`${this.label}`)
Button(`counter ${this.counter} +1`)
.onClick(() => {
this.counter += 1;
})
}
}
}
@Entry
@Component
struct MainView {
@State toggle: boolean = true;
build() {
Column() {
if (this.toggle) {
CounterView({ label: 'CounterView #positive' })
} else {
CounterView({ label: 'CounterView #negative' })
}
Button(`toggle ${this.toggle}`)
.onClick(() => {
this.toggle = !this.toggle;
})
}
}
}
CounterView (「CounterView #positive」というラベルが付いている) サブコンポーネントは、最初にレンダリングされるときに作成されます。このサブコンポーネントは、counter という名前の状態変数を保持します。CounterView.counter 状態変数が変更されると、CounterView (「CounterView #positive」というラベルが付いている) サブコンポーネントは再レンダリング時に状態変数値を保持します。MainView.toggle 状態変数の値が false に変更されると、MainView 親コンポーネント内の if ステートメントが更新され、その後 CounterView (「CounterView #positive」というラベルが付いている) 子コンポーネントが削除されます。同時に、新しい CounterView (「CounterView #negative」というラベルが付いている) インスタンスが作成されます。また、自身のカウンタ状態変数は初期値 0 に設定されます。
注: CounterView (ラベルは「CounterView #positive」) と CounterView (ラベルは「CounterView #negative」) は、同じカスタム コンポーネントの 2 つの異なるインスタンスです。if ブランチを変更しても、既存のサブコンポーネントは更新されず、状態も保存されません。
次の例は、条件が変化したときにカウンタ値を保持するために行う必要のある変更を示しています。
@Component
struct CounterView {
@Link counter: number;
label: string = 'unknown';
build() {
Row() {
Text(`${this.label}`)
Button(`counter ${this.counter} +1`)
.onClick(() => {
this.counter += 1;
})
}
}
}
@Entry
@Component
struct MainView {
@State toggle: boolean = true;
@State counter: number = 0;
build() {
Column() {
if (this.toggle) {
CounterView({ counter: $counter, label: 'CounterView #positive' })
} else {
CounterView({ counter: $counter, label: 'CounterView #negative' })
}
Button(`toggle ${this.toggle}`)
.onClick(() => {
this.toggle = !this.toggle;
})
}
}
}
ここで、@State カウンター変数は親コンポーネントによって所有されています。したがって、CounterView コンポーネントのインスタンスが削除されても、変数は破棄されません。CounterView コンポーネントは、@Link デコレータを通じて状態を参照します。条件付きコンテンツまたは重複コンテンツが破棄されたときに状態が失われないように、状態を子からその親 (または親の親) に移動する必要があります。
3. ネストされた if ステートメント
条件ステートメントのネストは、親コンポーネントの関連ルールに影響を与えません。
@Entry
@Component
struct CompA {
@State toggle: boolean = false;
@State toggleColor: boolean = false;
build() {
Column() {
Text('Before')
.fontSize(15)
if (this.toggle) {
Text('Top True, positive 1 top')
.backgroundColor('#aaffaa').fontSize(20)
// 内部if语句
if (this.toggleColor) {
Text('Top True, Nested True, positive COLOR Nested ')
.backgroundColor('#00aaaa').fontSize(15)
} else {
Text('Top True, Nested False, Negative COLOR Nested ')
.backgroundColor('#aaaaff').fontSize(15)
}
} else {
Text('Top false, negative top level').fontSize(20)
.backgroundColor('#ffaaaa')
if (this.toggleColor) {
Text('positive COLOR Nested ')
.backgroundColor('#00aaaa').fontSize(15)
} else {
Text('Negative COLOR Nested ')
.backgroundColor('#aaaaff').fontSize(15)
}
}
Text('After')
.fontSize(15)
Button('Toggle Outer')
.onClick(() => {
this.toggle = !this.toggle;
})
Button('Toggle Inner')
.onClick(() => {
this.toggleColor = !this.toggleColor;
})
}
}
}