HarmonyOS 鸿蒙Next基于Navigation的路由管理
HarmonyOS 鸿蒙Next基于Navigation的路由管理
Navigation介绍
Navigation简介
- Navigation:路由导航的根视图容器,一般作为页面(@Entry)的根容器去使用,包括单页面(stack)、分栏(split)和自适应(auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。一次开发,多端部署场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。
- Title:标题栏,通过title属性对标题栏进行设置。通过menus配置菜单
- NavContent:内容区域,默认首页显示导航内容(Navigation的子组件)或非首页显示(NavDestination的子组件),首页和非首页通过路由进行切换。
- ToolBar:工具栏,通过toolbarConfiguration实现对工具栏的配置,如果不配置此属性,ToolBar不显示。竖屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。
- NavDestination:作为子页面的根容器,用于显示Navigation的内容区。具备两种类型:STANDARD(标准类型,NavDestination的生命周期跟随NavPathStack栈中标准NavDestination变化而改变),DIALOG(默认透明。不影响其他NavDestination的生命周期)。
- NavPathStack:Navigation路由栈,由于管理NavDestination组件的路由跳转。推荐使用NavPathStack配合navDestination属性进行页面路由。
Navigation路由页面生命周期简介
Navigation由NavDestination组件组成页面路由,在实现过程中NavDestination组件会被封装在一个自定义组件中,从而作为一个页面被路由栈使用。当前支持的生命周期函数:aboutToAppear、onReady、onAppear、onShow、onHide、onDisappear、aboutToDisappear 、onWillAppear、onWillDisappear
事件名称 | 描述 |
aboutToAppear | 自定义组件析构销毁之前执行。 |
onAppear | 组件挂载显示时触发此回调。 |
onReady | 当NavDestination即将构建子组件之前会触发此回调。 |
onShown | 当该NavDestination页面显示时触发此回调。 |
onHidden | 当该NavDestination页面隐藏时触发此回调。 |
onDisAppear | 组件卸载消失时触发此回调。 |
aboutToDisappear | 在自定义组件析构销毁之前执行。 |
Navigation VS Router
当前HarmonyOS支持两套路由机制(Navigation和Router),Navigation作为后续长期演进及推荐的路由选择方案,其与Router比较的优势如下:
- 易用性层面:
- Navigation天然具备标题、内容、回退按钮的功能联动,开发者可以直接使用此能力。Router若要实现此能力,需要自行定义;
- Navigation的页面是由组件构成,易于实现共享元素的转场。
- 功能层面:
- Navigation天然支持一多,Router不支持;
- Navigation没有路由数量限制,Router限制32个;
- Navigation可以获取到路由栈NavPathStack,并对路由栈进行操作;
- Navigation可以嵌套在模态对话框中,也就是说可以模态框中定义路由,Router不支持;
- Navigation的组件全量由开发者自行控制,开发者可以自定义复杂的动效和属性的设置(背景、模糊等),Router的page对象不对外暴露,开发者无法对page进行处理。
- 性能层面
- Navigation传递参数性能更优,Navigation通过引用传递,Router通过深拷贝完成;
- Navigation可以配合动态加载,实现组件动态加载,Router页面使用@Entry进行修饰,当前模块加载时会生成全量页面。
Navigation & Router结构对比
- Navigation中的每个页面,承载在一个page里,通过NavDestination容器实现基于组件的页面跳转。
- Router的每一个页面配置在一个单独的page中,通过@Entry进行标识。
Navigation & Router能力对比
业务场景 | Navigation能力 | Router能力 |
跳转指定页面 | pushPath & pushDestination | pushUrl & pushNameRouter |
跳转HSP中页面 | 支持,需要先import页面 | 支持 |
跳转HAR中页面 | 支持,需要先import页面 | 支持 |
跳转传参 | 支持 | 支持 |
获取指定页面参数 | 支持 | 不支持 |
跳转结果回调 | 支持 | 支持 |
跳转单例页面 | 可通过判断栈内有没有此页面,调用moveToTop实现 | 支持 |
页面返回 | pop | back |
页面返回传参 | 支持 | 支持 |
返回指定路由 | popToName&popToIndex | 不支持 |
页面返回弹窗 | 通过路由拦截实现 | showAlertBeforeBackPage |
路由替换 | replacePath & replacePathByName | replaceUrl & replaceNameRouter |
路由栈清理 | clear | clear |
清理指定路由 | removeByIndexes & removeByName | 不支持 |
转场动画 | 支持 | 支持 |
自定义转场动画 | 支持 | 支持 |
屏蔽转场动画 | pushDestination(info: NavPathInfo, animated?: boolean) & patshStack.disableAnimation(true) | 支持 duration属性设置为0 |
共享元素动画 | 支持 | 不支持 |
页面生命周期监听 | UIObserver.on(‘navDestinationUpdate’) | UIObserver.on(‘routerPageUpdate’) |
获取页面栈对象 | 支持 | 不支持 |
路由拦截 | setInterception | 不支持 |
路由栈信息查询 | getAllPathName & getParamByIndex & getParamByName&size | getState() & getLength() |
路由栈操作 | moveToTop & moveIndexToTop | 不支持 |
沉浸式页面 | 支持 | 不支持,需通过window配置 |
设置页面属性(背景,模糊等) | 支持,backgroundBlurStyle | 不支持 |
设置页面标题栏(title)和工具栏(toolbar) | 支持 | 不支持 |
模态嵌套路由 | 支持 | 不支持 |
Navigation常见场景&解决方案
路由跳转场景
Navigation 目前就一个不太友好,就是replace 不能切换Navigation所在的组件。
比如 登录页面用了 Navigation后,登录完成跳转主业务页面,navstackpath.replacePath 后,最后返回还是会回到登录的。
所以我现在的方案是登录模块与主业务模块用router.replace切换,然后主业务mainPage 用Navgation ,登录模块也是Navigation, 只不过是两个navstackpath各自在自己的内部去跳转。
但是我也是学过Android碎片化的呀,意思就是当你有了一个Navigation之后其他业务页面都不是@Entry全都用NavDestination代替实现碎片化思路,我不知道这样理解对不对
仔细学习了Navigation,我感觉又不像是碎片化,只是后面加入了路由管理功能(官方建议使用,但是不一定是可以完全代替Router,看使用场景,不同模块建议用Router跳转)。为什么这么说呢?因为它只要有一个Navigation,就必然有一个页面生成加入到返回栈中,系统返回操作会去回退该界面。碎片化的问题我提交了工单,看华为怎么回复吧。
插眼期待回复
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
文中提到router支持单例页面,请问下这个怎么实现
我也试了,dialog模式不支持转场动画,应该是需要通过自定义动画来实现。
您好,当前技术文章配套的demo工程正在外发中,后续会发布至gitee上,敬请关注!