往期鸿蒙全套实战文章必看:(附带鸿蒙全栈学习资料)
如何实现跨模块的页面跳转功能
在业务体系庞大或复杂的情况下,通常会将业务拆分成多个子业务模块,单个子业务模块为一个har/hsp。在该场景下,通常存在从主业务入口跳转到不同子页面模块,或从一个子业务模块A页面跳转到另一个子业务模块B页面的需求。如,从应用首页跳转到登录子业务模块页面。 针对该场景,有以下三种解决方案:
- 方案一:使用router的命名路由接口router.pushNamedRoute()跳转。
参考地址: 页面路由 (@ohos.router)
- 方案二:使用navigation组件跳转。
以从应用入口模块的页面NavigationPage跳转到Login子业务模块页面LoginPage为例。主要包含以下步骤:
- 在Login模块中开发自定义组件LoginPage(路由跳转目的地),并对外导出。
@Component export struct LoginPage { @Consume('pathStack') pathStack: NavPathStack; @State message: string = 'Login Page'; build() { NavDestination() { Column() { Text(this.message) .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') .height('100%') } .onBackPressed(() => { this.pathStack.pop(); return true; }) } }
- 在Login模块的入口文件Index.ets中导出自定义组件。
export { LoginPage } from './src/main/ets/pages/loginPage';
- 在入口模块的oh-package.json5文件中添加对Login模块的依赖。
{ // ... "dependencies": { "@ohos/login": "file:../login" } }
- 入口模块LoginPage页面导入Login模块的自定义组件,并添加到Navigation组件的路由表中。
// 导入Login模块自定义组件 import { LoginPage } from '@ohos/login'; @Entry @Component struct NavigationPage { @Provide('pathStack') pathStack: NavPathStack = new NavPathStack(); @Builder pageMap(name: string) { if (name === 'loginPage') { LoginPage() } } build() { Navigation(this.pathStack) { Button('jump to login page') .onClick(() => { // NavPathInfo第二个参数为自定义参数,可用于信息传递 let pathInfo: NavPathInfo = new NavPathInfo('loginPage', new Object()); this.pathStack.pushDestination(pathInfo, true); }) } .navDestination(this.pageMap) } }
- 在Login模块中开发自定义组件LoginPage(路由跳转目的地),并对外导出。
- 方案三:使用基于navigation组件的自定义路由框架跳转。
方案二虽然可以实现跨模块跳转的功能,但当模块间跳转需求增多,各个模块间将存在非常复杂的依赖关系,甚至会导致多个har/hsp间循环依赖。为了解决模块间的强耦合关系,并且提升页面加载性能,推荐使用自定义路由框架。该方案的整体思路如下:
- 自定义一个路由管理模块RouterModule,各个需要使用路由功能的模块均依赖此模块。
- 路由管理模块RouterModule内部定义路由栈NavPathStack,并对NavPathStack进行封装,对外提供路由能力。
- 在使用Navigation组件时,需将Navigation组件对应的NavPathStack注册到路由管理模块中。通过路由管理模块RouterModule的NavPathStack对路由能力进行控制。
- 各个路由页面不再提供组件,转为提供@builder封装的构建函数,再通过WrappedBuilder封装进行传递使用。
- 各个路由页面将模块名称、路由名称、WrappedBuilder封装后的构建函数注册到路由管理模块RouterModule的路由表中。
- 当路由需要跳转到指定路由时,调用路由管理模块RouterModule的push方法。该方法对指定的模块的路由页面动态导入,并完成路由跳转。
完整方案设计可参考:应用导航设计。