系列:HarmonyOS 开发入门 · 07

搜索 HarmonyOS 页面跳转时,你很容易同时看到 router.pushUrl()Navigation / NavPathStack 两套写法。

如果只是照着旧文章抄,很容易把一个新项目写成“能跳,但不好维护”的状态。

先给结论:新项目优先考虑 Navigation。

1. router 为什么看起来更简单

传统页面路由写起来很直观:

router.pushUrl({
  url: 'pages/Detail'
})

页面就是文件路径,学习成本低。

对于早期小 Demo,这套方式确实够快。

问题在于项目变大以后,你会遇到:

  • 页面栈管理;
  • 单例跳转;
  • 路由拦截;
  • 跨模块路由;
  • 平板分栏;
  • 页面级转场;
  • 统一 Navigation 状态。

这时纯粹靠 URL 页面跳转会越来越吃力。

2. Navigation 的核心不是“另一个 push API”

Navigation 由几个关键角色组成:

Navigation
└── NavDestination

NavPathStack 负责管理页面栈

Navigation 是导航容器;NavDestination 是子页面根容器;NavPathStack 负责页面入栈、出栈、替换等操作。

也就是说,它从一开始就在解决“页面栈”问题。

3. 最小 Navigation 示例

@Entry
@Component
struct Index {
  private pathStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pathStack) {
      Column({ space: 16 }) {
        Text('首页')
          .fontSize(28)

        Button('进入详情')
          .onClick(() => {
            this.pathStack.pushPath({
              name: 'DetailPage',
              param: { id: 1001 }
            })
          })
      }
    }
    .hideTitleBar(true)
  }
}

这里的关键变化是:

页面跳转不再围绕“文件 URL”,而是围绕“导航栈中的页面名称”。

4. Navigation 对大项目更友好

例如系统路由表可以把页面名称和页面实现配置起来。

router_map.json

{
  "routerMap": [
    {
      "name": "DetailPage",
      "pageSourceFile": "src/main/ets/pages/DetailPage.ets",
      "buildFunction": "DetailPageBuilder"
    }
  ]
}

再在 module.json5 注册:

{
  "module": {
    "routerMap": "$profile:router_map"
  }
}

业务代码只关心:

this.pathStack.pushPath({ name: 'DetailPage' })

这就比各处散落页面路径更容易统一管理。

5. 平板和折叠屏也是一个关键原因

Navigation 支持 StackSplitAuto 等显示模式。

手机上可以是单栏页面栈,屏幕足够宽时可以切成分栏。

如果项目本身考虑手机 + 平板 + 折叠屏,从一开始采用 Navigation 会更顺。

6. 那 router 还能不能用

能不能用和新项目应该怎么选,是两个问题。

存量项目里已经大量使用 router,没有必要为了“跟新”立刻全部重写。

但新项目如果路线明确,我不会再用旧路由方式搭整个页面体系,然后半年后再迁移。

7. 我实际会怎么定规则

团队项目里我通常会约定:

  • 主业务页面统一 Navigation;
  • 页面名称集中管理;
  • 页面参数定义明确类型;
  • 路由拦截统一做登录态等逻辑;
  • 不允许业务代码随处硬编码页面字符串。

比如:

export class Routes {
  static readonly HOME: string = 'HomePage'
  static readonly DETAIL: string = 'DetailPage'
  static readonly SETTINGS: string = 'SettingsPage'
}

至少比几十个页面到处写魔法字符串可靠。

8. 一个容易忽略的问题

Navigation 学习成本比 router 高一点,但不要因此把所有页面都写在一个 PageMap() 里做巨大 if/else

Demo 可以,真实项目还是应该配合路由表、模块拆分和明确的页面 Builder。

总结

如果只是看 API:router 更短。

如果看工程:Navigation 更像一套完整导航体系。

所以我的选择是:Demo 可以理解 router,正式新项目直接把 Navigation 学透。

下一篇会把 NavPathStack 页面跳转、传参、返回、替换和系统路由表完整串起来。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐