> 技术文档 > 鸿蒙HarmonyOS Navigation:路由操作全解析_鸿蒙 navigation

鸿蒙HarmonyOS Navigation:路由操作全解析_鸿蒙 navigation

目录

一、HarmonyOS 路由系统简介

二、Navigation 组件基础认知

(一)Navigation 是什么

(二)显示模式全览

(三)与 Router 的对比优势

三、Navigation 路由操作实战

(一)前期准备工作

(二)页面跳转操作

(三)页面返回操作

(四)页面替换与删除

(五)页面参数获取

四、实践案例展示

(一)简单应用示例

(二)复杂业务场景应用

五、常见问题与解决方案

(一)路由跳转失败

(二)参数传递异常

六、总结与展望


一、HarmonyOS 路由系统简介

在 HarmonyOS 应用开发的广袤天地中,路由系统宛如一座城市的交通枢纽,是确保应用流畅运行、用户体验无缝衔接的关键要素。它负责管理应用内页面之间的跳转与导航,就如同城市交通规划决定了人们如何高效地从一个地点前往另一个地点。当用户在应用中进行操作,比如从首页点击进入详情页,又或者在不同功能模块间切换时,背后正是路由系统在默默运作,精准地引导着页面的切换与交互。

Navigation 路由操作作为 HarmonyOS 路由系统的核心组成部分,更是开发者手中强大的工具。它允许开发者以一种灵活且高效的方式定义应用的页面路径,实现页面之间的平滑跳转。无论是简单的单页面应用,还是复杂的多模块大型应用,Navigation 都能大显身手,帮助开发者构建清晰、易用的用户导航结构 ,让用户在应用中畅行无阻,轻松找到所需功能与信息。

二、Navigation 组件基础认知

(一)Navigation 是什么

在 HarmonyOS 的开发体系中,Navigation 是一个至关重要的路由容器组件,它就像是应用这座大厦的交通枢纽核心,负责管理应用内各个页面之间的路由关系 ,让开发者能够轻松实现页面的跳转与切换。简单来说,它定义了应用内页面的路径规则,就如同城市的道路地图,指引着用户如何从一个页面顺畅地到达另一个页面。无论是从应用的首页跳转到详情页,还是在不同功能模块间穿梭,Navigation 都能精准地完成任务,确保用户体验的连贯性与流畅性。它为开发者提供了一种高效、灵活的方式来构建应用的导航结构,使得应用的页面管理变得有条不紊。

(二)显示模式全览

Navigation 组件提供了三种强大的显示模式,以适应各种不同的设备屏幕尺寸和应用场景需求。

  1. 自适应(Auto)模式:这是一种智能的显示模式,它如同一位聪明的设计师,能够根据设备屏幕的宽度自动选择最适合的布局方式。当设备屏幕较宽时,比如在平板电脑上,它会自动切换为分栏模式,充分利用屏幕空间,同时展示多个相关信息,就像在大屏上一边显示文章列表,一边展示文章详情,让用户可以快速浏览和深入阅读;而当屏幕较窄时,如在普通手机上,它又会巧妙地切换为单栏模式,保证内容展示的简洁与清晰,不会让用户感到杂乱。
  1. 单栏(Stack)模式:这种模式下,页面以堆叠的方式呈现,就像一叠卡片,每次只展示一个页面,新页面会覆盖在当前页面之上 。当用户进行页面跳转时,新页面会从屏幕底部向上滑动进入,旧页面则向下滑动退出,给用户一种流畅的页面切换体验。这种模式非常适合内容展示较为单一、注重页面间层级关系的应用场景,比如新闻详情页的跳转,从新闻列表点击进入详情,就可以通过单栏模式清晰地展示内容的递进关系。
  1. 分栏(Split)模式:在大屏设备上,分栏模式大放异彩。它将屏幕划分为多个区域,同时展示不同的内容,就像一本杂志的对页布局,用户可以在同一屏幕上同时查看不同模块的信息。例如,在一个邮件客户端应用中,左侧区域可以显示邮件列表,右侧区域显示选中邮件的详细内容,用户无需频繁跳转页面,就能高效地处理邮件,大大提高了操作效率和用户体验。

开发者可以通过设置 Navigation 组件的 mode 属性轻松选择所需的显示模式,如mode: NavigationMode.Auto即可开启自适应模式,灵活掌控应用的页面展示效果。

(三)与 Router 的对比优势

在 HarmonyOS 路由系统中,除了 Navigation,还有 Router 也用于页面路由管理,但 Navigation 在诸多方面展现出独特的优势。

从功能丰富度来看,Navigation 天然支持 “一多” 关系,即一个导航可以对应多个子页面,这种灵活的映射关系能够满足更多复杂业务场景的需求。而 Router 则不具备这一特性,在处理复杂页面结构时稍显逊色。并且,Navigation 没有路由数量的限制,开发者可以自由地定义和管理大量的路由,不用担心数量上限的问题;Router 却限制了最多只能有 32 个路由,这在大型应用开发中可能会成为束缚。此外,Navigation 可以获取到路由栈 NavPathStack,并对其进行各种操作,如入栈、出栈、清空等,方便开发者精细控制页面的跳转历史和状态 ;Router 则不提供这样直接操作路由栈的能力。Navigation 还可以嵌套在模态对话框中,实现模态框内的路由定义,为应用增加了更多交互设计的可能性,Router 在这方面却无能为力。

在易用性层面,Navigation 具有天生的优势。它天然具备标题、内容、回退按钮的功能联动,开发者无需额外编写复杂的代码,就可以直接使用这些功能,节省了开发时间和精力。例如,当页面跳转时,标题会自动更新,回退按钮也能正确响应,保证用户操作的便捷性;而 Router 若要实现这些功能,就需要开发者自行定义和实现,增加了开发的难度和工作量。Navigation 的页面由组件构成,这使得实现共享元素的转场效果变得轻而易举,为用户带来更加流畅和自然的页面切换动画,提升用户体验;Router 在共享元素转场方面的支持则相对有限。

从性能角度分析,Navigation 在传递参数时采用引用传递的方式,相比 Router 通过深拷贝完成参数传递,大大提高了数据传递的效率,减少了内存的消耗和数据传输的时间,尤其在传递大量数据时,优势更加明显。同时,Navigation 可以配合动态加载技术,实现组件的动态加载,只有在需要时才加载相应的组件,有效提升了应用的启动速度和运行性能;而 Router 的页面使用 @Entry 进行修饰,在当前模块加载时会生成全量页面,这可能会导致应用启动缓慢,占用更多内存资源。

三、Navigation 路由操作实战

(一)前期准备工作

在正式开启 Navigation 路由操作的奇妙之旅前,我们需要精心做好一系列前期准备工作,为后续的开发工作筑牢根基。

首先,要创建至关重要的路由配置文件。在项目的 profile 文件夹下,新建一个名为router_map.json5的文件。这个文件堪称应用路由的 “导航地图”,其基本格式遵循 JSON5 规范 ,内容主要是定义一个个路由映射规则。例如:


{

\"routerMap\": [

{

\"name\": \"homePage\",

\"pageSourceFile\": \"src/main/ets/pages/HomePage.ets\",

\"buildFunction\": \"HomePageBuilder\"

},

{

\"name\": \"detailPage\",

\"pageSourceFile\": \"src/main/ets/pages/DetailPage.ets\",

\"buildFunction\": \"DetailPageBuilder\"

}

]

}

在这里,name代表页面的唯一标识名称,就像每个人的身份证号一样独一无二;pageSourceFile指明了页面源文件在项目中的具体路径,如同详细的家庭住址;buildFunction则是指向被@Builder修饰的函数,这个函数负责构建页面的用户界面,是页面展示的关键所在。通过这样清晰的配置,我们就为应用的页面跳转规划好了清晰的路径。

接下来,我们要在所属模块的module.json5文件中进行配置。找到routerMap字段 ,将其值设置为刚刚创建的路由配置文件路径,例如\"routerMap\": \"$profile:router_map.json5\"。这一步就像是在应用的 “大脑” 中注册了我们的路由地图,让应用知道从哪里获取页面的路由信息,从而能够准确无误地实现页面之间的跳转。完成这一步后,我们的前期准备工作就基本就绪,为后续精彩的路由操作搭建好了坚实的舞台。

(二)页面跳转操作

在 HarmonyOS 应用开发中,页面跳转是用户在应用内进行交互的常见操作,Navigation 提供了丰富多样的方式来实现这一功能,以满足各种不同的业务需求。

最基础的便是普通跳转,使用pushPathByName方法可以轻松实现。假设我们在一个电商应用中,从商品列表页面跳转到商品详情页面,代码示例如下:


import { NavPathStack } from \'@ohos.app.ability\';

// 创建NavPathStack对象

let pageStack: NavPathStack = new NavPathStack();

// 普通跳转,跳转到名为detailPage的页面,携带商品ID参数

pageStack.pushPathByName(\'detailPage\', { productId: \'12345\' });

在这段代码中,pushPathByName方法接收两个参数,第一个参数\'detailPage\'是目标页面在路由配置文件中定义的名称,它就像是目的地的地址,告诉应用要跳转到哪个页面;第二个参数{ productId: \'12345\' }是一个对象,用于传递参数到目标页面,这里传递的是商品 ID,目标页面可以根据这个 ID 来展示对应的商品详情信息,让用户能够深入了解商品的具体情况。

当我们需要在页面返回时获取一些信息,比如在一个登录页面,用户登录成功后返回原页面,并携带登录后的用户信息,这时就可以使用带返回回调的跳转。示例代码如下:


pageStack.pushPathByName(\'loginPage\', null, (popInfo) => {

if (popInfo.result) {

let userInfo = popInfo.result;

console.log(\'用户登录成功,返回的用户信息:\', userInfo);

// 在这里可以根据返回的用户信息进行相应的操作,比如更新用户界面显示

} else {

console.log(\'用户取消登录或登录失败\');

}

});

在这个例子中,pushPathByName方法多了一个回调函数参数(popInfo) => {...}。当从目标页面(这里是loginPage)返回时,会触发这个回调函数。popInfo对象包含了返回的相关信息,其中popInfo.result就是目标页面返回的数据。如果用户登录成功,popInfo.result会携带用户信息,我们就可以在回调函数中获取并处理这些信息,为用户提供更加个性化的体验。

有时候,页面跳转可能会因为各种原因失败,比如目标页面不存在、参数传递错误等,这时候我们就需要捕获错误码并进行处理。使用带错误码的跳转可以很好地解决这个问题,代码示例如下:


pageStack.pushDestinationByName(\'detailPage\', { productId: \'12345\' })

.catch((error) => {

console.error(\'页面跳转失败,错误码:\', error.code, \',错误信息:\', error.message);

// 可以根据错误码进行不同的处理,比如提示用户不同的错误原因

})

.then((

国防生信息平台