鸿蒙:Navigation的布局和路由跳转使用方法

hm688c71fd6d54b
发布于 2025-10-16 11:17
浏览
0收藏

我们还是和之前一样,参考官方文档学习,并且将其作为我们实践的依据,链接如下:

​文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-navigation​

如果你已经大致浏览了官方文档中的参数介绍和示例介绍,还是有些小问题,那么可以继续往下看。

  1. 创建Navigation和NavDestination页面【重点】
  2. 创建标题栏(title),菜单栏(menus)
  3. 使用导航控制器实现路由跳转【重点】

1、创建Navigation页面和NavDestination页面:

你可以理解Navigation是父组件,NavDestination是子组件。当然你也可以理解Navigation是根组件。所以,Navigation只有一个即可,NavDestination可以有多个。理解了后我们继续往下。

我们在根页面使用Navigation()组件包裹内容,在需要跳转到的页面使用NavDestination()组件包裹内容。接下来我来做个演示。

Index.ets 【这是根页面,根组件就用Navigation() 】

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  
  build() {
    Navigation() {
      Column(){
        Button("跳转到PageOne")
      }
      .height('100%')
      .width('100%')
      .justifyContent(FlexAlign.Center)
    }
    
  }
}

PageOne.ets 和 PageTwo.ets 是需要跳转的子页面,使用NavDestination()包裹内容

@Component
export struct PageOne {
  build() {
NavDestination(){
  Column(){
    Button("跳转到PageTwo")
  }
  .height("100%")
  .width("100%")
  .justifyContent(FlexAlign.Center)
}
  }
}

@Component
export struct PageTwo {
  build() {
    NavDestination(){
      Column(){
        Button("返回上一页")
      }
      .height("100%")
      .width("100%")
      .justifyContent(FlexAlign.Center)
    }

  }
}

2、创建标题栏(title),菜单栏(menus)

这一步可以根据自己的需要可配可不配,我们直接复制官方示例代码到Index.ets中,然后绑定到Navigation()组件上:

@Entry
  @Component
  struct Index {
    @State message: string = 'Hello World';
    @Builder
    NavigationTitle() {
      Column() {
        Text('Title')
          .fontColor('#182431')
          .fontSize(30)
          .lineHeight(41)
          .fontWeight(700)
        Text('subtitle')
          .fontColor('#182431')
          .fontSize(14)
          .lineHeight(19)
          .opacity(0.4)
          .margin({ top: 2, bottom: 20 })
      }.alignItems(HorizontalAlign.Start)
    }

    @Builder
    NavigationMenus() {
      Row() {
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
          .margin({ left: 24 })
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
          .margin({ left: 24 })
      }
    }

    build() {
      Navigation() {
        Column(){
          Button("跳转到PageOne")
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
      }
      .title(this.NavigationTitle)
      .menus(this.NavigationMenus)

    }
  }

3、使用导航控制器实现路由跳转【重点】

前面主要是通过配置组件,实现页面的正常显示,但是此时并不能跳转,如果想跳转,还需以下步骤:

①在NavDestination()组件包裹的页面,配置跳转组件的Builder函数,格式如下:

@Builder
export function PageOneBuilder(name: string, param: Object) {
  PageOne()
}

②设置路由跳转控制器,格式如下:

pageInfos: NavPathStack = new NavPathStack();

注意:要将控制器绑定到Navigation()组件,下面会有代码展示

③注册路由表,在如图所示的目录下注册,格式如下:

鸿蒙:Navigation的布局和路由跳转使用方法-鸿蒙开发者社区cke_2529.png

{
  "routerMap": [
    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is pageOne"
      }
    },
    {
      "name": "pageTwo",
      "pageSourceFile": "src/main/ets/pages/PageTwo.ets",
      "buildFunction": "PageTwoBuilder"
    }
  ]
}

④在module.json5中注册路由表

将我们③步创建的路由表在这里注册下,不然会出现跳转到空白页的情况:

"routerMap": "$profile:route_map",

如果以上看完了,我们就开始实战,项目运行效果和完整代码如下:

鸿蒙:Navigation的布局和路由跳转使用方法-鸿蒙开发者社区cke_5358.png

鸿蒙:Navigation的布局和路由跳转使用方法-鸿蒙开发者社区cke_7602.png

鸿蒙:Navigation的布局和路由跳转使用方法-鸿蒙开发者社区cke_9935.png

Index.ets

export  const   pageInfos: NavPathStack = new NavPathStack();


@Entry
  @Component
  struct Index {
    @State message: string = 'Hello World';
    @Builder
    NavigationTitle() {
      Column() {
        Text('Title')
          .fontColor('#182431')
          .fontSize(30)
          .lineHeight(41)
          .fontWeight(700)
        Text('subtitle')
          .fontColor('#182431')
          .fontSize(14)
          .lineHeight(19)
          .opacity(0.4)
          .margin({ top: 2, bottom: 20 })
      }.alignItems(HorizontalAlign.Start)
    }

    @Builder
    NavigationMenus() {
      Row() {
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
          .margin({ left: 24 })
        Image($r("app.media.startIcon"))
          .width(24)
          .height(24)
          .margin({ left: 24 })
      }
    }

    build() {
      Navigation(pageInfos) {
        Column(){
          Button("跳转到PageOne")
            .onClick(()=>{
              pageInfos.pushPath({ name: 'pageOne' });
            })
        }
        .height('100%')
        .width('100%')
        .justifyContent(FlexAlign.Center)
      }
      .title(this.NavigationTitle)
      .menus(this.NavigationMenus)

    }
  }

PageOne.ets

import { pageInfos } from "./Index"

@Builder
export function PageOneBuilder() {
  PageOne()
}
@Component
export struct PageOne {
  build() {
NavDestination(){
  Column(){
    Button("跳转到PageTwo")
      .onClick(()=>{
        pageInfos.pushPath({ name: 'pageTwo' });
      })
  }
  .height("100%")
  .width("100%")
  .justifyContent(FlexAlign.Center)
}
  }
}

PageTwo.ets

import { pageInfos } from "./Index";

@Builder
export function PageTwoBuilder() {
  PageTwo()
}
@Component
export struct PageTwo {
  build() {
    NavDestination(){
      Column(){
        Button("返回上一页")
          .onClick(()=>{
            pageInfos.pop()
          })
      }
      .height("100%")
      .width("100%")
      .justifyContent(FlexAlign.Center)
    }

  }
}

NavigationDemo\entry\src\main\resources\base\profile\route_map.json

{
  "routerMap": [

    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is pageOne"
      }
    },
    {
      "name": "pageTwo",
      "pageSourceFile": "src/main/ets/pages/PageTwo.ets",
      "buildFunction": "PageTwoBuilder"
    }
  ]
}

NavigationDemo\entry\src\main\module.json5

{
  "module": {
    "routerMap": "$profile:route_map",
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "ohos.want.action.home"
            ]
          }
        ]
      }
    ],
    "extensionAbilities": [
      {
        "name": "EntryBackupAbility",
        "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
        "type": "backup",
        "exported": false,
        "metadata": [
          {
            "name": "ohos.extension.backup",
            "resource": "$profile:backup_config"
          }
        ],
      }
    ]
  }
}

以上是个人经验分享。

文章来源:​​https://developer.huawei.com/consumer/cn/blog/topic/03195995279885138​

分类
标签
收藏
回复
举报
回复
    相关推荐