> 技术文档 > 鸿蒙中Navigation跳转最简便用法,详细实现步骤,附上源码_鸿蒙navigation跳转

鸿蒙中Navigation跳转最简便用法,详细实现步骤,附上源码_鸿蒙navigation跳转


概述

在鸿蒙开发中路由跳转官方推荐使用Navigation替代router进行路由跳转,本文将从Navigation的使用步骤入手,一步步带着各位玩转Navigation路由跳转,以及注意事项

 这里是官方文档入口:

Navigation-导航与切换-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5

特性 Navigation Router 功能 支持复杂的路由逻辑,如多级路由嵌套、动态路由配置等 主要通过URL识别和定位页面,适用于基本的页面跳转 页面栈管理 提供强大的页面栈管理功能,可以轻松获取和操作页面栈 对页面栈的管理能力较弱,难以进行精细化操作 使用方式 采用组件化的方式,代码更灵活,便于维护和扩展 需要在配置文件中定义路由规则,代码结构相对固定 参数传递 支持传递对象、数组等复杂数据类型,数据传递更安全和可靠 主要通过URL的查询参数传递数据,对于复杂数据结构传递不够方便 性能 功能强大,经过优化,性能表现能满足复杂应用的需求 在处理复杂路由逻辑时可能会出现性能瓶颈 适用场景 适用于模块内页面切换和复杂动效场景,推荐用于新开发的项目 适用于模块间页面跳转和简单的页面间跳转

 1、第一步在项目根组件套上Navigation

在项目的根组件上套上,Navigation,这里有几个点需要注意,当设置了tab栏时页面出现布局不正常时可用设置下面两个属性,这两个属性可以将导航栏和内容区独立显示,避免出现布局问题

.mode(NavigationMode.Stack) // 导航栏与内容区独立显示,相当于两个页面。.titleMode(NavigationTitleMode.Mini) // 标题栏模式

 设置之前:如图所示,很明显,这里页面被挤上来了

设置之后:如图,这里布局正常了,并且出现了一个返回按钮,这里可以使用以下属性禁用这个原生标题。

.hideTitleBar(true) 

 

2、创建并传递NavPathStack

在使用Navigation时被跳转的组件必须被navDestination包裹,要实现跳转,Navigation必须绑定一个NavPathStack实例对象用于控制页面跳转,NavPathStack配合navDestination属性进行页面路由。本文案例使用的是@Provide和@Consume去进行NavPathStack,这两个装饰器可以进行跨代传递,要注意一点,@Consume接收的变量名必须和@Provide传出的变量名保持一致,否则会导致程序崩溃

NavPathStack绑定:

 // 绑定导航栈 Navigation(this.stackPath)

创建以及传递:

 // 导航栈创建以及传递 @Provide stackPath: NavPathStack = new NavPathStack();

子组件接收:

 // 接收stackPath @Consume stackPath: NavPathStack

3、子组件被NavDestination包裹,并导出一个全局@Builder

 子组件如下:

import { IParams } from \'../Index\'@Componentexport struct SubPage1 { // 接收stackPath @Consume stackPath: NavPathStack @State params: IParams = { message: \'点击我获取参数\', param: \'\' } build() { NavDestination() { Column({ space: 30 }) { Text(\"我是SubPage1\") .fontSize(30) .fontWeight(FontWeight.Bold) Text(this.params.param ? this.params.param : this.params.message) .fontSize(50) .fontWeight(FontWeight.Bold) .onClick(() => { const paramsFromIndex = this.stackPath.getParamByName(\'SubPage1\') as IParams[] if (paramsFromIndex.length) {  this.params = paramsFromIndex[0] } }) Button(\'返回\') .onClick(() => { this.stackPath.pop() }) } .width(\'100%\') .height(\'100%\') .justifyContent(FlexAlign.Center) } .width(\'100%\') .height(\'100%\') }}// 导出的全局 Builder@Builderfunction SubPage1Builder() { SubPage1()}

4、配置路由 

要让咱们的跳转能准确找到去跳转的页面,需要在src/main/resources/base/profile路径下添加router_map文件并配置routerMap

配置的routerMap如下:

{ \"routerMap\": [ { \"name\": \"SubPage1\", // 路由名称 \"buildFunction\": \"SubPage1Builder\", // 构建函数 \"pageSourceFile\": \"src/main/ets/pages/subPages/SubPage1.ets\" // 页面源文件 } ]}

在module.json5文件里配置刚创建的routerMap

5、使用navPathStack控制跳转,以及传参

当做好以上操作之后,即可去进行路由的跳转了,这里name要和routerMap里边的name字段对应上,跳转方式有多种,这里以pushParh为例:

  // 跳转 this.stackPath.pushPath({  // 路由名称  name: \'SubPage1\',  // 参数  param: {  message: \'index过来的参数\',  param: \'123456\'  } as IParams })

返回,这里在子组件中使用@Consume接收到的navPathStack控制返回

 Button(\'返回\') .onClick(() => { this.stackPath.pop() })

至此Navigation的一个配置流程以及跳转操作就完成了。

最后附上完整代码以及效果图

src/main/resources/base/profile下新建的router_map.json文件

{ \"routerMap\": [ { \"name\": \"SubPage1\", \"buildFunction\": \"SubPage1Builder\", \"pageSourceFile\": \"src/main/ets/pages/subPages/SubPage1.ets\" } ]}

在module.json5中配置routerMap:

{ \"module\": { \"routerMap\": \"$profile:router_map\", // 配置引用路由表 \"name\": \"entry\", \"type\": \"entry\", \"description\": \"$string:module_desc\", \"mainElement\": \"EntryAbility\", \"deviceTypes\": [ \"phone\", \"tablet\", \"2in1\" ], \"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\": [  \"action.system.home\" ] } ] } ], \"extensionAbilities\": [ { \"name\": \"EntryBackupAbility\", \"srcEntry\": \"./ets/entrybackupability/EntryBackupAbility.ets\", \"type\": \"backup\", \"exported\": false, \"metadata\": [ { \"name\": \"ohos.extension.backup\", \"resource\": \"$profile:backup_config\" } ], } ] }}

根组件Index.ets

export interface IParams { message: string; param: string;}@Entry@Componentstruct Index { @State message: string = \'跳转去下一个页面\'; // 导航栈创建以及传递 @Provide stackPath: NavPathStack = new NavPathStack(); build() { // 绑定导航栈 Navigation(this.stackPath) { Tabs() { TabContent() { Column() { Text(\'Navigation跳转\')  .fontSize(40)  .fontWeight(FontWeight.Bold) Button(this.message)  .fontWeight(FontWeight.Bold)  .onClick(() => { // 跳转 this.stackPath.pushPath({  // 路由名称  name: \'SubPage1\',  // 参数  param: {  message: \'index过来的参数\',  param: \'123456\'  } as IParams })  }) }.height(\'100%\') .width(\'100%\') .backgroundColor(\'#88E1DA\') .justifyContent(FlexAlign.Center) }.tabBar(\'一栏\') TabContent() { Column() { Text(\'我是第二栏\')  .fontSize(30)  .fontWeight(FontWeight.Bold) } }.tabBar(\'二栏\') }.barPosition(BarPosition.End) } .mode(NavigationMode.Stack) // 导航栏与内容区独立显示,相当于两个页面。 .titleMode(NavigationTitleMode.Mini) // 标题栏模式 .hideTitleBar(true) .height(\'100%\') .width(\'100%\') }}

子组件SubPage1.ets:

import { IParams } from \'../Index\'@Componentexport struct SubPage1 { // 接收stackPath @Consume stackPath: NavPathStack @State params: IParams = { message: \'点击我获取参数\', param: \'\' } build() { NavDestination() { Column({ space: 30 }) { Text(\"我是SubPage1\") .fontSize(30) .fontWeight(FontWeight.Bold) Text(this.params.param ? this.params.param : this.params.message) .fontSize(50) .fontWeight(FontWeight.Bold) .onClick(() => { const paramsFromIndex = this.stackPath.getParamByName(\'SubPage1\') as IParams[] if (paramsFromIndex.length) {  this.params = paramsFromIndex[0] } }) Button(\'返回\') .onClick(() => { this.stackPath.pop() }) } .width(\'100%\') .height(\'100%\') .justifyContent(FlexAlign.Center) } .width(\'100%\') .height(\'100%\') }}// 导出的全局 Builder@Builderfunction SubPage1Builder() { SubPage1()}

主页面

子页面,点击获取参数前:

 子页面,点击获取参数后