TabContent + If动态改变页面UI,结果切换TabContent时,触发if逻辑,导致页面重渲染明显,体验很不好 (HarmonyOS 鸿蒙Next)

TabContent + If动态改变页面UI,结果切换TabContent时,触发if逻辑,导致页面重渲染明显,体验很不好 (HarmonyOS 鸿蒙Next)

TabContent + If动态改变页面UI,结果切换TabContent时,触发if逻辑,导致页面重渲染明显,体验很差。理论上,TabContent初始化一次后,不会再改变,页面不会频繁重渲染,但是下方代码每次切换TabContent,就会重新渲染一次

示例代码:

@Entry
@Component
struct MainPage {
  @Provide('appPathStack') appPathStack: NavPathStack = new NavPathStack();
  @State index: number = 0;
  @State isShow: boolean = false;
  @State arr: Array<string> = ['1', '2', '3']

  onPageShow(): void {
    this.isShow = !this.isShow
  }

  build() {
    Tabs() {
      ForEach(this.arr, (item: string) => {
        TabContent() {
          Column() {
            Text('页面' + item)
          }
          .justifyContent(this.index == 1 ? FlexAlign.Start : FlexAlign.End)
          .alignItems(HorizontalAlign.Center)
          .width('100%')
          .height('100%')
        }
      }, (item: string) => item)
    }.onChange((index: number) => {
      this.index = index
    })
  }
}

更多关于TabContent + If动态改变页面UI,结果切换TabContent时,触发if逻辑,导致页面重渲染明显,体验很不好 (HarmonyOS 鸿蒙Next)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

分析上面代码,Tabs+ TabContent原理,进入页面之后,Tabs会一次加载所有TabContent,且切换时不会再触发刷新TabContent。

上面代码,反复触发TabContent UI布局刷新,理论上不负责TabContent的机制,那么为什么会刷新UI呢?分析代码后发现,justifyContent的属性,判断时使用的this.index == 1,因为index是TabContent的索引,且被@State修饰,导致index切换时,就会触发TabContent UI刷新。

修改方式:.justifyContent(this.index == 1 ? FlexAlign.Start : FlexAlign.End)修改成使用foreach的索引进行判断,就不会触发UI刷新了。

修改示例代码:

@Entry
@Component
struct MainPage {
  @Provide('appPathStack') appPathStack: NavPathStack = new NavPathStack();
  [@State](/user/State) index: number = 0;
  [@State](/user/State) isShow: boolean = false;
  [@State](/user/State) arr: Array<string> = ['1', '2', '3']

  onPageShow(): void {
    this.isShow = !this.isShow
  }

  build() {
    // 增加数组aindex
    ForEach(this.arr, (item: string, aIndex: number) => {
      TabContent() {
        Column() {
          Text('页面' + item)
        }
        // 使用数组aindex进行判断
        .justifyContent(aIndex == 1 ? FlexAlign.Start : FlexAlign.End)
        .alignItems(HorizontalAlign.Center)
        .width('100%')
        .height('100%')
      }
    }, (item: string) => item)
  }
}

更多关于TabContent + If动态改变页面UI,结果切换TabContent时,触发if逻辑,导致页面重渲染明显,体验很不好 (HarmonyOS 鸿蒙Next)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


看吧,楼上说的很清楚咯

.<function>(justifyContent)(this.index == 1 ? FlexAlign.Start : FlexAlign.End)

这一行代码的原因咯, 状态属性慎用哦,this.index

~~
ForEach(this.arr, (item: string, itemIndex: number) =&gt; {
        TabContent() {
          ...
          .<function>(justifyContent)(itemIndex == 1 ? FlexAlign.Start : FlexAlign.End)
          ...
        }
      }, (item: string) =&gt; item)

在鸿蒙Next中,TabContentIf结合使用时,切换TabContent会触发If的逻辑判断,导致页面重新渲染,影响用户体验。这是因为If组件在条件发生变化时会重新创建或销毁其子组件,从而引起页面的重渲染。

为了避免这种情况,可以考虑使用Visibility组件替代If组件。Visibility组件通过控制子组件的显示与隐藏,而不是创建或销毁子组件,从而减少页面的重渲染。具体实现方式是将If的判断逻辑改为Visibilityvisible属性控制。

例如,将以下代码:

if (condition) {
    // UI组件
}

改为:

Visibility({ visible: condition }) {
    // UI组件
}

这样在切换TabContent时,Visibility组件只会控制子组件的显示与隐藏,而不会触发页面的重渲染,从而提升用户体验。

回到顶部