HarmonyOS 页面路由与导航开发


网罗开发 (小红书、快手、视频号同名)

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员

👋 大家好,我是展菲!

📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。

📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 3 月 17 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!

文章目录

前言

HarmonyOS 应用通常由多个页面组成,页面之间的跳转、传参以及返回栈管理,都依赖路由与导航能力。ArkTS 提供了基于「路由」的页面模型,理解其用法和生命周期,能避免「跳转失败」「参数丢失」「返回键行为异常」等问题。

本文只讲路由与导航的核心 API 和典型用法,不贴完整工程,方便快速接入和排查问题。

路由与页面栈

在 HarmonyOS 中,每个「可被路由到的页面」对应一个用 @Entry 装饰的组件,路由地址在模块的 main_pages.json 中配置。跳转时通过 router 的 API 压栈或替换页面,返回时弹栈。

配置路由表 main_pages.json

src/main/resources/base/profile/main_pages.json 中声明页面路径与组件名:

json 复制代码
{
  "src": [
    "pages/Index",
    "pages/Detail",
    "pages/UserCenter"
  ]
}
  • pages/Index 表示 ets/pages/Index.ets 中导出的 @Entry 页面,路由 path 一般为 pages/Index
  • 未在此声明的页面无法通过路由跳转

跳转:pushUrl 与 replaceUrl

router.pushUrl() 会在当前栈顶再压入一个新页面;router.replaceUrl() 会替换当前栈顶页面(当前页被销毁,无法再返回回来)。

无参跳转:

typescript 复制代码
import router from '@ohos.router'

// 跳转到详情页,可返回
router.pushUrl({ url: 'pages/Detail' })

// 替换当前页为登录页,当前页无法返回
router.replaceUrl({ url: 'pages/Login' })

带参跳转:

typescript 复制代码
router.pushUrl({
  url: 'pages/Detail',
  params: {
    id: 100,
    from: 'list'
  }
})

params 会随路由传递,在目标页通过 router.getParams() 读取。

目标页接收参数

在详情页(例如 Detail.ets)的 onPageShow()aboutToAppear() 中获取参数:

typescript 复制代码
import router from '@ohos.router'

@Entry
@Component
struct Detail {
  @State id: string = ''
  @State from: string = ''

  aboutToAppear() {
    const params = router.getParams() as Record<string, Object>
    if (params) {
      this.id = String(params['id'] ?? '')
      this.from = String(params['from'] ?? '')
    }
  }

  build() {
    Column() {
      Text(`id: ${this.id}, from: ${this.from}`)
    }
  }
}

注意:getParams() 返回类型为 Object,实际使用建议做类型断言或安全取值,避免运行时异常。

返回与传参

返回上一页用 router.back();需要把结果带回上一页时,可传 params

typescript 复制代码
router.back({
  url: 'pages/Index',
  params: {
    result: 'ok',
    selectedId: 200
  }
})

上一页在再次显示时(例如 onPageShow())通过 router.getParams() 可拿到这次返回携带的 params。注意:返回时的 params 只在「返回目标页」重新显示时有效,若目标页已不在栈顶,需要自己设计数据回传方式(如全局状态、回调接口等)。

生命周期与路由

页面生命周期和路由紧密相关,常用回调有:

  • aboutToAppear() :页面即将显示前调用一次,适合做数据初始化、读 router.getParams()
  • onPageShow():每次页面显示时调用(首次进入、从子页返回都会触发),适合刷新列表、重新读返回参数
  • aboutToDisappear():页面即将销毁前调用,适合释放资源、取消订阅

典型用法:

typescript 复制代码
@Entry
@Component
struct Detail {
  aboutToAppear() {
    const params = router.getParams()
    // 根据 params 请求详情接口、设置标题等
  }

  onPageShow() {
    // 从子页返回时可能带回 params,在这里处理
    const params = router.getParams()
    if (params && params['refresh']) {
      // 重新拉取数据
    }
  }

  aboutToDisappear() {
    // 取消网络请求、解绑监听等
  }
}

这样能保证「进页拿参数、返回来刷新、离开时收尾」。

除了整页跳转,ArkUI 还提供 Tab 切换、NavRouter 等「容器内导航」组件,用于同一页面内多内容区切换。

Tabs 简单用法

typescript 复制代码
@Entry
@Component
struct TabDemo {
  @State currentIndex: number = 0

  @Builder
  TabBuilder(title: string, index: number) {
    Text(title)
      .fontSize(18)
      .fontColor(this.currentIndex === index ? '#007AFF' : '#666666')
      .onClick(() => {
        this.currentIndex = index
      })
  }

  build() {
    Tabs({ barPosition: BarPosition.Start, index: this.currentIndex }) {
      TabContent() {
        Text('首页内容')
      }
      .tabBar(this.TabBuilder('首页', 0))

      TabContent() {
        Text('我的内容')
      }
      .tabBar(this.TabBuilder('我的', 1))
    }
    .onChange((index: number) => {
      this.currentIndex = index
    })
  }
}

通过 indexonChange 把「当前选中的 Tab」与 @State currentIndex 同步,即可实现点击 Tab 栏和滑动内容联动。

NavRouter 配合 NavDestination 可做「侧边/底部导航 + 多子页」结构:点击导航项切换对应的 NavDestination,适合设置、个人中心等多级入口。使用方式为在 NavRouter 下放多个 NavDestination,通过 navDestination 属性绑定,用 isSelected 或路由状态控制当前展示的 Destination,具体 API 以当前版本文档为准。

常见问题

现象 可能原因 处理思路
pushUrl 报错找不到页面 未在 main_pages.json 中配置 检查 path 与 json 中 src 一致、编译后资源是否包含该页
目标页拿不到 params 在 aboutToAppear 之前就用了 getParams、或未用 params 传 在 aboutToAppear/onPageShow 里取参,pushUrl 时带上 params
返回后上一页数据不更新 未在 onPageShow 里处理返回 params 在 onPageShow 中 getParams 并刷新列表/表单
替换页后仍能返回 用了 pushUrl 而非 replaceUrl 登录后跳首页等「不可回退」场景用 replaceUrl

总结

HarmonyOS 页面路由依赖 main_pages.jsonrouterpushUrl / replaceUrl 负责跳转与传参,getParams() 在目标页取参,back() 可带参返回。结合 aboutToAppearonPageShowaboutToDisappear 处理生命周期,即可完成「进页初始化、返回来刷新、离开收尾」。Tabs、NavRouter 等组件用于单页内的多内容区导航,与整页路由配合使用即可覆盖大部分导航场景。

相关推荐
以太浮标2 小时前
华为eNSP模拟器综合实验之- VLAN终结实践案例分析
网络·计算机网络·华为·智能路由器
希望上岸的大菠萝3 小时前
HarmonyOS 6.0 开发环境搭建完全指南 - DevEco Studio 配置 + 真机调试实战
华为·harmonyos
Lancker3 小时前
定制侠 一个国产纯血鸿蒙APP的诞生过程
android·华为·智能手机·鸿蒙·国产操作系统·纯血鸿蒙·华为鸿蒙
大雷神4 小时前
HarmonyOS智慧农业管理应用开发教程--高高种地--第28篇:用户中心与个人资料
华为·harmonyos
雨季6664 小时前
破界与共生:HarmonyOS原生应用生态全景图谱与PC时代三重变局
flutter·华为·harmonyos
一路阳光8514 小时前
华为mate80现在确实没有日日新了,看来华为是对鸿蒙6有信心了
华为·harmonyos
三掌柜6664 小时前
如何从一个开发者成为鸿蒙KOL
华为·harmonyos
哈基米~南北绿豆4 小时前
虚拟机体验:在Windows/Mac上运行鸿蒙PC开发环境
windows·macos·harmonyos
爱笑的眼睛114 小时前
学着学着 我就给这个 HarmonyOS 应用增加了些新技术
华为·ai·harmonyos