HarmonyOS 鸿蒙Next中Tabs切换TabContent时为什么会页面重渲染

HarmonyOS 鸿蒙Next中Tabs切换TabContent时为什么会页面重渲染

问题现象:

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
    })
  }
}

更多关于HarmonyOS 鸿蒙Next中Tabs切换TabContent时为什么会页面重渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

看吧,楼上说的很清楚咯

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

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

~~

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

更多关于HarmonyOS 鸿蒙Next中Tabs切换TabContent时为什么会页面重渲染的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


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

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

修改方式:.justifyContent(aIndex == 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)
  }
}

在HarmonyOS鸿蒙Next中,Tabs切换TabContent时页面重渲染的原因主要是为了确保每个TabContent的状态和UI能够正确更新。每次切换Tab时,系统会销毁当前TabContent的视图并重新创建新的TabContent视图,以保证数据的准确性和UI的一致性。这种机制虽然会带来一定的性能开销,但能有效避免状态残留和UI错乱问题。开发者可以通过优化布局和减少不必要的重绘来提升性能。

回到顶部