在这里插入图片描述

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

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括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 中声明页面路径与组件名:

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

跳转:pushUrl 与 replaceUrl

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

无参跳转:

import router from '@ohos.router'

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

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

带参跳转:

router.pushUrl({
  url: 'pages/Detail',
  params: {
    id: 100,
    from: 'list'
  }
})

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

目标页接收参数

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

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

router.back({
  url: 'pages/Index',
  params: {
    result: 'ok',
    selectedId: 200
  }
})

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

生命周期与路由

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

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

典型用法:

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

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

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

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

导航类组件:Tabs 与 NavRouter

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

Tabs 简单用法

@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

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 等组件用于单页内的多内容区导航,与整页路由配合使用即可覆盖大部分导航场景。

Logo

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

更多推荐