路由的选择
HarmonyOS提供两种路由实现的方式,分别是 Router 和 NavPatchStack。两者使用场景和特效各有优劣。
组件 | 适用场景 | 特点 | 备注 |
---|---|---|---|
Router | 模块间与模块内页面切换 | 通过每个页面的url实现模块间解耦 | |
NavPathStack | 模块内页面切换 | 通过组件级路由统一路由管理 |
- 什么时候使用 NavPatchStack ?
如果是单包应用开发,不使用动态包(hsp)进行拆包,只是使用静态包(har)简单的进行模块拆分,那么我推荐使用 navPatchStack
。
- 什么时候使用 Router ?
如果像开发 鸿蒙元服务
,对单包体积有 2M
的限制,那么我们不得不使用动态包的方式。将相对独立的功能,二级页面等拆分出去,封装成动态包,可避开 dependencies
直接依赖得引用形式。
此时使用 router 跳转 url 的方式才可跳转到动态包内非直接引用的页面
NavPatchStatck 如何跳转(传参)及页面回调
NavPathStack 是配合 Navigation 一起使用的,
Navigation导航组件做统一的页面跳转管理,它提供了一系列属性方法来设置页面的标题栏、工具栏以及菜单栏的各种展示样式。
如何跳转(传参)及实现页面回调?
Router 如何跳转(传参)及页面回调
Router 跳转可支持跳转本包内页面以及动态包或者拆包内的页面,
- url 的定义举例如下:
- url 跳转
- 注意: 使用 router + url 进行跳转的目标页面必须使用 @Entry 修饰,且在main_pages.json 文件内填写对应路径
重点:截止 API11 版本,router 支持传递的 params 传参,不是引用传递,所以在动态包内实际获取到的不是同一个对象,为了实现页面回调,router 我们需要做如下封装:
- 如何跳转(传参)及实现页面回调?抛砖引玉 —
- 在公共的har包内定义 Router 管理类 FastRouter
(在下文扩展中解释单例为什么这么实现)
- 任一页面使用 FastRouter 进行 url 跳转
- 在目标页面内接收入参并回调结果
总结
NavPatchStack 和 Router 两种路由方式各有优劣,NavPatchStack 方便统一管理,Router 方便解耦,两者没有任何关联,可以一起使用,也可以单独使用。
扩展:动态包、静态包的使用差异
说到动态包(HAR)和静态包(HSP),这里扩展一下两者的区别。
静态包的 module.json5 文件,type 标识为 har
静态包的 module.json5 文件,type 标识为 shared
动态包和静态包都可以被直接引用,在 oh-package.json5
内
重点:
- 动态包可以不直接依赖( 例如:使用 preload ),跳转动态包内的页面可以通过
router
拼接url
进行跳转 - har 中的代码和资源跟随使用方编译,如果有多个使用方,存在多个 hap,也包括使用了 hsp 的场景。该 har 的编译产物中会存在多份相同拷贝。
存在两种情况,如果harA和harB都依赖harC,单个hap依赖harA、harB,那么只会存在一份harA、harB、harC;如果harA和harB都依赖harC,有两个hap,hapA依赖harA,hapB依赖harB,那么最终会存在一份harA、harB,两份harC;
- hsp 中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份
举个例子:
- 如果应用内没有使用动态包,或者把单例的封装放在动态包里被其他包(静态包或动态包)直接依赖,我们的单例可以这么写:
-
在应用的任意一处获取这个单例都是同一个对象
-
但如果单例封装放在 har 包内,该 har 包被其他包(静态包和动态包)依赖引用。仍然使用上述代码实现单例,我们在 entry 或者 被 entry 直接依赖的 har 中获取到的 SimgleProvider 单例 和在 hsp 包内获取到的 SimgleProvider 单例 不是指向同一份内存,它会被拷贝两份。
可以简单的总结为:一个应用内,同一个 har 包,如果同时被 har (或者entry)和 hsp 依赖引用,会被拷贝两份。
- 如果需要整个应用内,包括 entry、har、hsp 都指向的是同一个单例对象,要么把这个单例封装放在 hsp 内,如果单例封装放在 har 内,需要把上面的单例实现代码改成如下:
- 借助AppStorage,实现全应用单例
上述示例demo已上传,请参考下方链接
附注(Example)
Demo 示例已上传:
GitHub: https://github.com/liyufengrex/HarmonyAtomicService
GitCode: https://gitcode.com/liyufengrex/HarmonyAtomicService
(基于API11开发,支持NEXT及以上版本运行)已上传可供参考,包含如下内容:
- 静态库+动态包+多模块设计
- 状态管理
- 统一路由管理(router+navPathStack)
- 网络请求、Loading、Toast、数据持久化 等工具库封装
- 自定义组件、自定义弹窗(解耦)
- EventBus 事件通知
- 扩展修饰器,实现 节流、防抖、权限申请
- 动态路由 (navPathStack + 动态import + WrappedBuilder)
- UI动态节点操作 (BuilderNode + NodeController)
- 折叠屏适配示例
- 组件工厂示例
- 组件动态属性设置示例
补充
从 API version 12 开始,Navigation支持使用系统路由表的方式进行动态路由。各业务模块(HSP/HAR)中需要独立配置router_map.json文件(可参考上述demo内TestHspNavPathPage.ets
文件)。
具体可参考文档: Navigation系统路由