三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

OpenHarmony 页面路由与跨页面数据传递全解实战

OpenHarmony 页面路由与跨页面数据传递全解实战

承接前三篇 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)。
← 返回列表