HarmonyOS Navigation路由跳转的完整示例

HarmonyOS Navigation路由跳转的完整示例

项目概述

RouterNavigationDemo 是一个 HarmonyOS 应用示例项目,展示了如何在多模块架构中实现页面路由跳转。项目包含一个主模块(entry)和两个库模块(lib_harA 和 lib_hspA),演示了跨模块的页面导航功能。

项目结构

RouterNavigationDemo/
├── entry/                          # 主模块
│   ├── src/main/
│   │   ├── ets/
│   │   │   ├── entryability/      # 应用入口能力
│   │   │   │   └── EntryAbility.ets
│   │   │   └── pages/             # 页面文件
│   │   │       ├── Index.ets      # 首页
│   │   │       └── PageOne.ets    # 页面一
│   │   └── resources/
│   │       └── base/profile/
│   │           ├── main_pages.json    # 主页面配置
│   │           └── router_map.json    # 路由映射配置
├── lib_harA/                       # HAR 库模块
│   └── src/main/
│       ├── ets/pages/
│       │   └── HarAPageOne.ets    # HAR 页面一
│       └── resources/base/profile/
│           └── router_map.json    # HAR 路由映射
└── lib_hspA/                       # HSP 共享模块
    └── src/main/
        ├── ets/pages/
        │   └── HspAPageOne.ets    # HSP 页面一
        └── resources/base/profile/
            ├── main_pages.json    # HSP 主页面配置
            └── router_map.json    # HSP 路由映射

路由配置详解

1. 主模块 (entry) 配置

1.1 module.json5
{
  "module": {
    "name": "entry",
    "type": "entry",
    "mainElement": "EntryAbility",
    "pages": "$profile:main_pages",
    "routerMap": "$profile:router_map"
  }
}
1.2 main_pages.json
{
  "src": [
    "pages/Index"
  ]
}
1.3 router_map.json
{
  "routerMap": [
    {
      "name": "EntryPageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is PageOne"
      }
    }
  ]
}

2. HAR 库模块 (lib_harA) 配置

2.1 module.json5
{
  "module": {
    "name": "lib_harA",
    "type": "har",
    "routerMap": "$profile:router_map"
  }
}
2.2 router_map.json
{
  "routerMap": [
    {
      "name": "HarAPageOne",
      "pageSourceFile": "src/main/ets/pages/HarAPageOne.ets",
      "buildFunction": "HarAPageOneBuilder",
      "data": {
        "description": "this is HarAPageOne"
      }
    }
  ]
}

3. HSP 共享模块 (lib_hspA) 配置

3.1 module.json5
{
  "module": {
    "name": "lib_hspA",
    "type": "shared",
    "pages": "$profile:main_pages",
    "routerMap": "$profile:router_map"
  }
}
3.2 main_pages.json
{
  "src": [
    "pages/Index"
  ]
}
3.3 router_map.json
{
  "routerMap": [
    {
      "name": "HspAPageOne",
      "pageSourceFile": "src/main/ets/pages/HspAPageOne.ets",
      "buildFunction": "HspAPageOneBuilder",
      "data": {
        "description": "this is HspAPageOne"
      }
    }
  ]
}

页面路由关系图

                    ┌─────────────────┐
                    │     Index       │
                    │   (首页)        │
                    └─────────┬───────┘
                              │
                    ┌─────────┴───────┐
                    │                  │
        ┌───────────┴──────┐  ┌───────┴──────────┐  ┌───────────┴──────┐
        │   EntryPageOne   │  │    HarAPageOne   │  │    HspAPageOne   │
        │   (主模块页面)    │  │   (HAR库页面)    │  │   (HSP共享页面)  │
        └─────────┬────────┘  └────────┬─────────┘  └─────────┬────────┘
                  │                    │                      │
                  └────────────────────┼──────────────────────┘
                                       │
                    ┌─────────────────┴─────────────────┐
                    │           返回首页                │
                    │        (pathStack.clear())        │
                    └───────────────────────────────────┘

路由跳转实现

1. 首页 (Index.ets)

首页包含三个按钮,分别跳转到不同的页面:

// 跳转到主模块页面
Button($r('app.string.entry_pageOne'))
  .onClick(() => {
    this.pathStack.pushPathByName('EntryPageOne', '从首页到EntryPageOne');
  })

// 跳转到HAR库页面
Button($r('app.string.harA_pageOne'))
  .onClick(() => {
    this.pathStack.pushPathByName('HarAPageOne', '从首页到HarAPageOne');
  })

// 跳转到HSP共享页面
Button($r('app.string.hspA_pageOne'))
  .onClick(() => {
    this.pathStack.pushPathByName('HspAPageOne', '从首页到HspAPageOne');
  })

2. 主模块页面 (PageOne.ets)

// 返回首页
Button('toEntryIndex')
  .onClick(() => {
    this.pathStack.clear();
  })

// 跳转到HAR库页面
Button('to_HarA_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('HarAPageOne', '从EntryPageOne到HarAPageOne');
  })

// 跳转到HSP共享页面
Button('to_HspA_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('HspAPageOne', '从EntryPageOne到HspAPageOne');
  })

3. HAR库页面 (HarAPageOne.ets)

// 返回首页
Button('toEntryIndex')
  .onClick(() => {
    this.pathStack.clear();
  })

// 跳转到主模块页面
Button('to_Entry_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('EntryPageOne', '从HarAPageOne到EntryPageOne');
  })

// 跳转到HSP共享页面
Button('to_HspA_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('HspAPageOne', '从HarAPageOne到HspAPageOne');
  })

4. HSP共享页面 (HspAPageOne.ets)

// 返回首页
Button('toEntryIndex')
  .onClick(() => {
    this.pathStack.clear();
  })

// 跳转到主模块页面
Button('to_Entry_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('EntryPageOne', '从HspAPageOne到EntryPageOne');
  })

// 跳转到HAR库页面
Button('to_HarA_PageOne')
  .onClick(() => {
    this.pathStack.pushPathByName('HspAPageOne', '从HspAPageOne到HarAPageOne');
  })

关键API说明

1. NavPathStack

NavPathStack 是 HarmonyOS 提供的导航路径栈,用于管理页面导航状态:

  • pushPathByName(name: string, param?: Object): 通过页面名称推入新页面
  • clear(): 清空导航栈,返回首页

2. NavDestination

每个页面都包装在 NavDestination 组件中,提供导航上下文:

NavDestination()
  .onReady((context: NavDestinationContext) => {
    this.pathStack = context.pathStack;
    this.paramStr = context.pathInfo.param as string;
  })

3. Navigation

首页使用 Navigation 组件作为导航容器:

Navigation(this.pathStack) {
    // 页面内容
}

路由跳转流程

  1. 应用启动: EntryAbility 加载首页 Index
  2. 页面跳转: 用户点击按钮,调用 pathStack.pushPathByName() 跳转
  3. 参数传递: 跳转时可以传递参数,在目标页面的 onReady 回调中接收
  4. 返回首页: 调用 pathStack.clear() 清空导航栈,返回首页

注意事项

  1. 模块依赖: 确保在 oh-package.json5 中正确配置模块依赖关系
  2. 路由名称: 路由名称必须与 router_map.json 中的 name 字段一致
  3. 页面构建函数: 每个页面都需要提供对应的构建函数(如 PageOneBuilder
  4. 导航栈管理: 合理使用 clear() 方法,避免导航栈过深

总结

RouterNavigationDemo 项目展示了 HarmonyOS 中多模块页面路由跳转的完整实现方案,通过 NavPathStackrouter_map.json 配置,实现了跨模块的页面导航功能。这种架构设计使得应用具有良好的模块化特性,便于维护和扩展。

项目地址

<think>好的,我现在需要回答用户关于HarmonyOS页面跳转的最佳实践问题,特别是router和Navigation的选择。首先,我需要理解这两个组件的区别和各自的优缺点。根据提供的引用内容,Navigation有setInterception方法用于拦截回调,但步骤更繁琐,而router可能更简单但未来推荐转向Navigation。 接下来,我应该整理两者的主要区别。比如,router是声明式API,适合简单场景,而Navigation是命令式,适合复杂导航需求。然后要考虑性能方面,Navigation可能更高效,尤其是在处理复杂跳转逻辑时。此外,拦截器的支持也是一个关键点,Navigation提供的拦截功能对于权限控制或条件跳转很有用。 然后,最佳实践部分需要分场景讨论。如果是简单跳转,router更合适;需要拦截或动态导航的话,用Navigation。同时要提到未来推荐使用Navigation,尽管当前可能步骤多,但后续会更优化。代码示例也很重要,展示两者的基本用法,让用户更直观地理解。 还要注意引用标注,在提到拦截器和推荐转向Navigation的地方加上对应的引用标记。最后,生成的相关问题需要覆盖性能比较、拦截器实现、迁移步骤等,帮助用户深入探索。</think>### HarmonyOS router vs Navigation 页面跳转最佳实践 #### 1. 核心区别与适用场景 - **router(声明式路由)** 通过配置式语法实现页面跳转,适合简单的静态路由场景。例如: ```typescript router.pushUrl({ url: 'pages/DetailPage' }) ``` 优势在于代码简洁,但灵活性较低,适用于**无需动态控制跳转逻辑**的场景[^1]。 - **Navigation(命令式导航)** 通过代码控制跳转流程,支持动态拦截与参数传递。例如: ```typescript Navigation.get(this).navigateTo({ url: 'pages/DetailPage', params: { id: 123 } }) ``` 提供`setInterception`方法实现跳转拦截,适合需要**权限验证/条件跳转**的复杂场景[^2]。 #### 2. 性能与开发成本对比 | 维度 | router | Navigation | |---------------|-----------------------------|-----------------------------| | 启动速度 | 较快(预加载机制) | 略慢(动态加载组件) | | 内存占用 | 较低 | 较高(维护导航栈) | | 代码复杂度 | 低(<10行基础代码) | 高(需处理拦截回调) | #### 3. 最佳实践建议 - **优先选择router的场景** ✅ 新手快速开发 ✅ 无跳转条件判断的二级页面 ✅ 浅层级页面栈(≤3层) - **必须使用Navigation的场景** 🔑 需要登录状态拦截(通过`setInterception`实现) 🔑 动态参数传递(如实时定位信息) 🔑 复杂导航结构(底部导航栏+侧边栏) #### 4. 混合使用方案 ```typescript // 在拦截器中组合使用两种方式 Navigation.setInterception((params) => { if (needComplexCheck()) { Navigation.get(this).navigateTo({...}); return true; // 拦截原路由 } else { router.pushUrl({...}); return false; } }) ``` 此模式兼顾开发效率与灵活性,适合中型项目迭代[^3]。 #### 5. 未来演进方向 官方文档明确指出,**Navigation将成为路由系统的核心基础**,router后续将基于Navigation实现更高层封装。建议新项目逐步采用Navigation作为底层基础,同时通过封装工具类简化调用: ```typescript class NavHelper { static safePush(url: string) { if (checkPermission()) { Navigation.get(this).navigateTo({url}); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值