承接前三篇 ArkUI 组件开发,本篇聚焦Router 页面路由导航,覆盖页面跳转、返回传参、弹窗路由、命名路由、页面间数据交互,搭配完整 ArkTS 案例,是多页面应用开发必备内容。

一、前言

实际项目由多个页面组成(首页、详情、个人中心、登录页),依靠路由实现页面切换。OpenHarmony ArkUI 提供两种路由方案:Router(系统路由,页面跳转首选)页面内自定义弹窗路由,同时配套正向传参、反向回传数据能力。本文从基础跳转→参数传递→综合项目案例循序渐进。

前置配置:路由需要在src/main/resources/base/profile/main_pages.json注册页面路径。

二、main_pages.json 页面注册说明

新建页面后必须配置页面路由路径,示例配置:

json

{
  "src": [
    "pages/index/index",
    "pages/detail/detail",
    "pages/login/login"
  ]
}
  • index:首页(入口页面)
  • detail:详情页
  • login:登录页

三、Router 基础 API 与基础跳转

引入路由模块:import router from '@ohos.router' 常用方法:

  1. router.pushUrl():入栈跳转,可返回上一页(最常用)
  2. router.replaceUrl():替换当前页面,无法返回上一页
  3. router.back():返回上一级页面

3.1 普通无参跳转(首页 index.ets)

ets

import router from '@ohos.router'

@Entry
@Component
struct Index {
  build() {
    Column({space:20}){
      Button("跳转详情页(push)")
        .width(200)
        .onClick(()=>{
          router.pushUrl({url:"pages/detail/detail"})
        })

      Button("替换页面(replace)")
        .width(200)
        .onClick(()=>{
          router.replaceUrl({url:"pages/detail/detail"})
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

3.2 详情页返回(detail.ets)

ets

import router from '@ohos.router'

@Entry
@Component
struct Detail {
  build() {
    Column() {
      Text("详情页面").fontSize(22)
      Button("返回首页")
        .onClick(()=>{
          router.back()
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

四、正向页面传参(跳转携带数据)

跳转时通过params携带对象数据,目标页面router.getParams()接收。

4.1 首页携带参数跳转

ets

import router from '@ohos.router'

@Entry
@Component
struct Index {
  build() {
    Column({space:20}){
      Button("携带参数跳详情")
        .width(200)
        .onClick(()=>{
          router.pushUrl({
            url:"pages/detail/detail",
            params:{
              id:1001,
              name:"OpenHarmony实战教程",
              price:39.9
            }
          })
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

4.2 详情页接收参数

ets

import router from '@ohos.router'

@Entry
@Component
struct Detail {
  @State id:number = 0
  @State name:string = ""
  @State price:number = 0

  aboutToAppear(){
    // 生命周期获取路由参数
    let data = router.getParams()
    this.id = data.id
    this.name = data.name
    this.price = data.price
  }

  build() {
    Column({space:15}) {
      Text(`编号:${this.id}`).fontSize(18)
      Text(`标题:${this.name}`).fontSize(18)
      Text(`价格:${this.price}`).fontSize(18)
      Button("返回首页").onClick(()=>router.back())
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

五、返回页面反向回传数据(回调传参)

从子页面返回首页并带回数据,借助pushUrlsuccess回调接收回传参数。

5.1 首页代码

ets

import router from '@ohos.router'

@Entry
@Component
struct Index {
  @State backMsg:string = ""

  goDetail(){
    router.pushUrl({url:"pages/detail/detail"},{
      success:(res)=>{
        // 监听页面关闭带回的数据
        res.result.params && (this.backMsg = res.result.params.msg)
      }
    })
  }

  build() {
    Column({space:20}){
      Button("跳转详情(可回传数据)")
        .width(220)
        .onClick(()=>this.goDetail())
      Text("子页面带回信息:"+this.backMsg).fontSize(18)
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

5.2 详情页返回时携带参数

ets

import router from '@ohos.router'

@Entry
@Component
struct Detail {
  build() {
    Column() {
      Button("确认带回数据并返回")
        .onClick(()=>{
          // back携带params参数
          router.back({
            url:"pages/index/index",
            params:{msg:"从详情页返回:操作已完成!"}
          })
        })
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

六、页面路由综合实战:登录跳转逻辑

业务场景:未登录点击个人中心→跳转登录页,登录成功携带登录状态返回首页。

  1. pages/index/index(首页)

ets

import router from '@ohos.router'

@Entry
@Component
struct Index {
  @State isLogin:boolean = false
  @State userName:string = ""

  goLogin(){
    router.pushUrl({url:"pages/login/login"},{
      success:(res)=>{
        if(res.result.params){
          this.isLogin = res.result.params.loginFlag
          this.userName = res.result.params.name
        }
      }
    })
  }

  build() {
    Column({space:25}){
      if(this.isLogin){
        Text(`欢迎用户:${this.userName},已登录`).fontSize(20).fontColor("#007DFF")
      }else{
        Text("当前未登录,请前往登录").fontSize(18).fontColor("#f56c6c")
      }
      Button("前往登录页面")
        .width(200)
        .onClick(()=>this.goLogin())
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}
  1. pages/login/login(登录页)

ets

import router from '@ohos.router'

@Entry
@Component
struct Login {
  @State name:string = ""
  @State pwd:string = ""

  loginClick(){
    // 模拟登录校验
    if(this.name && this.pwd){
      router.back({
        params:{
          loginFlag:true,
          name:this.name
        }
      })
    }
  }

  build() {
    Column({space:18}){
      TextInput({placeholder:"请输入用户名"})
        .width("90%")
        .height(45)
        .onChange(val=>this.name=val)
      TextInput({placeholder:"请输入密码"})
        .type(InputType.Password)
        .width("90%")
        .height(45)
        .onChange(val=>this.pwd=val)
      Button("登录")
        .width("90%")
        .height(48)
        .backgroundColor("#007DFF")
        .onClick(()=>this.loginClick())
      Button("取消返回")
        .width("90%")
        .backgroundColor("#999")
        .onClick(()=>router.back())
    }
    .width("100%")
    .height("100%")
    .padding(20)
  }
}

七、开发规范与路由优化总结

1. API 选用规范

  • 需要保留返回栈(详情、登录):pushUrl
  • 不需要返回(启动页→首页):replaceUrl

2. 传参注意事项

  1. 简单字符串、数字、对象用路由 params 传递;大批量全局数据建议使用 AppStorage 全局存储;
  2. aboutToAppear生命周期中获取路由参数,不要在 build 直接取值,避免渲染异常。

3. 项目优化技巧

  1. 统一封装路由工具类,把页面路径统一管理,避免硬编码 URL;
  2. 路由跳转前做判空,防止路径书写错误导致跳转失败;
  3. 大型项目拆分模块页面,按业务分包(user、goods、mine)。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐