Tabs页面Navigation路由跳转的实现方式
=========================

#### 问题现象

使用Tabs组件结合Navigation组件实现页面跳转时，虽然TabContent能够成功跳转，但TabBar部分并未消失。

代码如下：

TempPage.ets文件：

import { tabsub } from './tabsub';


@Entry
@Component
struct TempPage {
  @State currentIndex: number = 0
  controller: TabsController = new TabsController()
  @Provide('appPathStack') appPathStack: NavPathStack = new NavPathStack();


  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
        ForEach(\['待办', '已办', '已发'\], (item: string, index: number) => {
          TabContent() {
            Navigation(this.appPathStack) {
              tabsub()
            }
          }.tabBar(this.tabBuilder(index, item))
        })
      }
      .vertical(false)
      .barWidth('100%')
      .barHeight(37)
      .onChange((index: number) => {
        this.currentIndex = index
      })
      .backgroundColor(Color.White)
      .width('100%')
      .margin({ top: 0, bottom: 0 })
    }
    .height('100%')
    .width('100%')
  }


  @Builder
  tabBuilder(index: number, name: string) {
    Column() {
      Text(name)
        .fontSize(14)
        .fontColor(this.currentIndex === index ? '#0A59F7' : '#666666')
        .fontWeight(this.currentIndex === index ? 500 : 400)
        .lineHeight(22)
      Divider()
        .strokeWidth(3)
        .color('#4A90E2')
        .opacity(this.currentIndex === index ? 1 : 0)
        .width(30)
      Divider()
        .strokeWidth(1)
        .color('#EEEEEE')
    }
    .backgroundColor(Color.White)
    .width('100%').height(44).justifyContent(FlexAlign.SpaceEvenly)
  }
}

tabsub.ets文件：

@Builder
export function tabsubBuilder() {
  tabsub();
}


@Component
export struct tabsub {
  @Consume('appPathStack') appPathStack: NavPathStack;


  build() {
    NavDestination() {
      Column() {
        Text('内容')
          .fontSize(30)
          .onClick(() => {
            this.appPathStack.pushPathByName('WebView', new Object({}));
          });
      }
      .height('100%')
      .width('100%')
      .border({ width: 1, radius: 20, color: '#f1f3f5' })
      .backgroundColor('#f1f3f5')
      .justifyContent(FlexAlign.Center);
    };
  }
}

WebView.ets文件：

@Builder
export function WebViewBuilder() {
  WebView();
}


@Component
export struct WebView {
  @Consume('appPathStack') appPathStack: NavPathStack;


  build() {
    NavDestination() {
      Column() {
        Text('test')
          .fontSize(30);
      }
      .height('100%')
      .width('100%')
      .backgroundColor('#f1f3f5')
      .justifyContent(FlexAlign.Center)
      .border({ width: 1, radius: 20, color: '#f1f3f5' });
    }
    .padding({ left: 16, right: 16, top: 16 })
    .hideBackButton(true);
  }
}

效果如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/82/v3/HqT8CPYyTUe8cFNHwlMMeg/zh-cn_image_0000002628569610.png?HW-CC-KV=V1&HW-CC-Date=20260709T134041Z&HW-CC-Expire=86400&HW-CC-Sign=87C48A882236A730C0865665F62D3B0C1C09BD9C1F6B5A1698D1259145FBF7FF "点击放大")

#### 背景知识

*   [Tabs](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-tabs)：通过页签进行内容视图切换的容器组件，每个页签对应一个内容视图。
*   [Navigation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation)：Navigation组件是路由导航的根视图容器，一般作为Page页面的根容器使用，其内部默认包含了标题栏、内容区和工具栏，其中内容区默认首页显示导航内容（[NavDestination](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navdestination)的子组件）或非首页显示（NavDestination的子组件），首页和非首页通过路由进行切换。
*   [routerMap](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/module-configuration-file#routermap标签)：此标签标识模块配置的路由表的路径。

#### 问题定位

根据代码逻辑排查出是由于Navigation组件放置TabContent内部导致的。

#### 分析结论

Navigation组件放置在TabContent内部，在页面跳转时，只能实现TabContent内容的替换并不能覆盖到TabBar部分。

#### 修改建议

将Navigation放到Tabs外层即实现跳转，同时需要在工程配置文件module.json5中配置{"routerMap": "$profile:router\_map"}。示例代码如下：

import { tabsub } from './tabsub';


@Entry
@Component
struct TempPage {
  @State currentIndex: number = 0;
  controller: TabsController = new TabsController();
  @Provide('appPathStack') appPathStack: NavPathStack = new NavPathStack();


  build() {
    Column() {
     _ // solution start_
      _// 将Navigation放到Tabs外层_
      Navigation(this.appPathStack) {
        Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
          ForEach(\['待办', '已办', '已发'\], (item: string, index: number) => {
            TabContent() {
              tabsub();
            }.tabBar(this.tabBuilder(index, item))
            .padding({ left: 16, right: 16, top: 16 })
            .width('100%')
            .height('100%');
          });
        }
        .vertical(false)
        .barWidth('100%')
        .barHeight(37)
        .onChange((index: number) => {
          this.currentIndex = index;
        })
        .backgroundColor(Color.White)
        .margin({ top: 0, bottom: 0 });
      }
      .hideToolBar(true);
   _   // solution end_
    }
    .height('100%')
    .width('100%');


  }


  @Builder
  tabBuilder(index: number, name: string) {
    Column() {
      Text(name)
        .fontColor(this.currentIndex === index ? '#0A59F7' : '#000000')
        .lineHeight(22);
      Divider()
        .strokeWidth(2)
        .color('#0A59F7')
        .opacity(this.currentIndex === index ? 1 : 0)
        .width(30);
      Divider()
        .strokeWidth(1)
        .color('#EEEEEE');
    }
    .backgroundColor(Color.White)
    .width('100%').height(44).justifyContent(FlexAlign.SpaceEvenly);
  }
}

效果如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/c7/v3/ZAV3-hWdSzKBtRMsbva2cw/zh-cn_image_0000002628409710.png?HW-CC-KV=V1&HW-CC-Date=20260709T134041Z&HW-CC-Expire=86400&HW-CC-Sign=1FAEF6E8CFE07C7AA0BFF5493144B495A383F0153C2A87A38E90E3B5D60E432E "点击放大")

#### 常见FAQ

Q：Navigation双栏模式下切换Tab页签，右边页面未切换成对应子页面。

A：点击切换Tab页签时触发[onTabBarClick](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-container-tabs#ontabbarclick10)事件，在此事件中清空路由栈并切换到对应子页面。