在鸿蒙Next开发中,ArkTS提供了强大的渲染控制能力,其中条件渲染(if/else)可根据应用不同状态显示相应UI内容。以下是对其用法的详细总结。

一、使用规则

1. 语句支持

支持if、else和else if语句,可灵活构建条件判断逻辑。

2. 变量类型

if、else if后的条件语句可使用状态变量(值改变实时渲染UI)或常规变量(值改变不实时渲染UI)。

3. 使用位置

允许在容器组件内使用,构建不同子组件,但要遵循容器组件对子组件的限制。例如,Grid容器内使用条件渲染时,其内部只能使用GridItem组件。

4. 父子关系

条件渲染语句在父子组件关系中是“透明”的,需遵守父组件对子组件的使用规则。

5. 构建函数

每个分支内部的构建函数必须创建一个或多个组件,空构建函数会产生语法错误。

二、更新机制

当if、else if后的状态判断中状态变量值变化时,条件渲染语句更新,步骤如下:

  1. 评估条件判断条件,若分支无变化则停止更新。
  2. 若分支有变化,删除此前构建的所有子组件。
  3. 执行新分支的构造函数,将获取的组件添加到if父容器中(若无else分支则不构建内容)。注意,条件中的表达式不得更改应用程序状态。

三、使用场景

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语句执行构建函数添加子组件。状态变量变化时,重新评估条件,若变化则按更新机制重建UI。如count从0变为1,满足条件后创建新Text组件并添加;count变回0时,该Text组件被删除(无else分支不执行新构造函数)。

2. if...else...语句和子组件状态

  • 示例一(不保留状态)
@Component
struct CounterView {
  @State counter: number = 0;
  label: string = 'unknown';
  build() {
    Column({ space: 20 }) {
      Text(`${this.label}`)
      Button(`counter ${this.counter} +1`)
       .onClick(() => {
          this.counter += 1;
        })
    }
   .margin(10)
   .padding(10)
   .border({ width: 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;
        })
    }
   .width('100%')
   .justifyContent(FlexAlign.Center)
  }
}
  • 解释:CounterView(label为'CounterView #positive')子组件初渲染时创建,含状态变量counter。修改counter时该子组件重渲染保留值。但当MainView.toggle变为false,原CounterView子组件被删,新建CounterView(label为'CounterView #negative')实例且counter设为初始值0,因为if分支更改不更新现有子组件且不保留状态。
  • 示例二(保留状态)
@Component
struct CounterView {
  @Link counter: number;
  label: string = 'unknown';
  build() {
    Column({ space: 20 }) {
      Text(`${this.label}`)
       .fontSize(20)
      Button(`counter ${this.counter} +1`)
       .onClick(() => {
          this.counter += 1;
        })
    }
   .margin(10)
   .padding(10)
   .border({ width: 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;
        })
    }
   .width('100%')
   .justifyContent(FlexAlign.Center)
  }
}
  • 说明:此处@State counter变量归父组件,子组件通过@Link引用。当CounterView实例删除时变量不销毁,从而在条件更改时保留counter值。

3. 嵌套if语句

  • 示例
@Entry
@Component
struct CompA {
  @State toggle: boolean = false;
  @State toggleColor: boolean = false;
  build() {
    Column({ space: 20 }) {
      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;
        })
    }
   .width('100%')
   .justifyContent(FlexAlign.Center)
  }
}
  • 原理:条件语句嵌套不影响父组件规则,可按需求构建复杂条件判断逻辑,通过外层和内层if语句及状态变量控制UI显示。

掌握鸿蒙Next的条件渲染用法,能根据应用状态精准控制UI展示,提升应用的交互性和用户体验。在实际开发中,需根据具体场景灵活运用这些规则和特性。


严肃的烤土司
1 声望0 粉丝