页面路由

官方不推荐使用页面路由,这里仅做简单介绍。

页面路由用于标识 @Entry 注解的页面间的跳转。

包引入

import { router } from'@kit.ArkUI';

页面跳转

  1. router.pushUrl 目标页面不会替换当前页,而是压入页面栈
  2. router.replaceUrl 目标页面会替换当前页,并销毁当前页

Router模块提供了两种实例模式,分别是Standard和Single,决定了目标url是否会有对应多个实例

//无参数跳转
router.replaceUrl({
url: 'pages/PageA' // 目标url
}, router.RouterMode.Standard, (err) => {
if (err) {
console.error(`${err.code}, ${err.message}`);
return;
}
console.info('succeeded.');
})
//携带参数跳转
class DataModel {
name: string = ""
age: number = 0;
}
toPageA() {
let params: DataModel = {
name: "张三",
age: 20,
}
router.pushUrl({
url: "pages/PageA",
params: params
})
}
//在目标页面获取参数
const params: DataModel = router.getParams() as DataModel;

页面返回

通过router.back 返回上一个页面或指定页面

//返回上一个页面
router.back();
//返回到指定页面
router.back({
url: 'pages/Home'
});
//返回时传递参数
router.back({
url: 'pages/Home',
params: {
info: 'back parmas'
}
});
//返回参数获取,在返回目标页面的OnPageShow中获取参数
onPageShow() {
const params = this.getUIContext().getRouter().getParams() as Record<string, string>; // 获取传递过来的参数对象
if (params) {
const info: string = params.info as string; // 获取info属性的值
}
}

命名路由

@Entry({ routeName: 'pageA' })
@Component
export struct MyComponent {
build() {
……
}
} toPageA() {
router.pushNamedRoute({
name: "pageA",
})
}

组件导航(Navigation)

Navigation 是路由容器组件,一般作为首页的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。

在不同尺寸的设备上,Navigation组件能够自适应显示大小,自动切换分栏展示效果。

Navigation组件主要包含导航页(NavBar)和子页(NavDestination)。导航页由标题栏(Titlebar,包含菜单栏menu)、内容区(Navigation子组件)和工具栏(Toolbar)组成,其中导航页可以通过 hideNavBar 属性进行隐藏,导航页不存在页面栈中,导航页和子页,以及子页之间可以通过路由操作进行切换。

显示模式

单页面模式示意图



分栏模式示意图

  1. 自适应模式:NavigationMode.Auto
  2. 单页面模式:NavigationMode.Stack
  3. 分栏模式:NavigationMode.Split
Navigation() {
// ...
}
.mode(NavigationMode.Stack) //页面模式设置为单页面模式

标题栏

标题栏模式包括:Mini模式和Full模式

Mini模式示意图

Full模式示意图

菜单栏

菜单栏位于Navigation组件的右上角,通过menus属性进行设置。传递数组时,竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。

菜单栏支持 CustomBuilder 参数,用来传入自定义布局。

工具栏

工具栏位于Navigation组件的底部,通过toolbarConfiguration属性进行设置。

工具栏支持 CustomBuilder 参数,用来传入自定义布局。

navPathStack: NavPathStack = new NavPathStack()

Navigation(this.navPathStack) {
// ...
}
.titleMode(NavigationTitleMode.Full) //设置标题栏模式
.menus([{ //设置菜单栏
value:"menu1",
icon:"resources/base/media/icon1.png",
action:()=>{ }
},{
value:"menu2",
icon:"resources/base/media/icon2.png",
action:()=>{ }
}])
.toolbarConfiguration([ //设置工具栏
{
value: "tab1",
icon: $r('app.media.scan_multiple_result'),
action:()=>{ }
},
{
value: "tab2",
icon: $r('app.media.scan_one_result'),
action:()=>{ }
},,
{
value: "tab3",
icon: $r('app.media.startIcon'),
action:()=>{ }
},
])

路由表配置

  1. 创建跳转页面入口Builder函数
@Builder
export function PageOneBuilder() {
PageOne()
} @Component
export struct PageOne {
@Consume('navPathStack') navPathStack: NavPathStack build() {
NavDestination() {
}.title("Page1")
}
}
  1. 在resources/base/profile中创建route_map.json文件,配置如下:

    name:路由名称

    pageSourceFile:目标页在保内的路径,相对src目录的相对路径

    buildFunction:跳转目标页的入口函数名称,必须以@Builder修饰

    data:应用自定义字段。可以通过配置项读取接口getConfigInRouteMap获取
{
"routerMap": [
{
"name": "PageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description" : "this is PageOne"
}
}
]
}
  1. 配置文件module.json5添加路由表配置
 {
"module" : {
"routerMap": "$profile:route_map"
}
}

路由表另一种实现方式:

  1. 创建Builder函数
  2. 通过Navigation的navDestination()方法创建路由表
@Builder
PageMap(name: string) {
if (name === "page1") {
PageOne()
} else if (name === "page2") {
PageTwo()
} else if (name === "page3") {
PageThree()
}
} Navigation(this.navPathStack) {
……
}.navDestination(this.PageMap)

页面导航

页面导航通过 NavPathStack 的相关接口实现

//跳转page1
this.navPathStack.pushPath({ name: "page1", param: "page1 param" })
this.navPathStack.pushPathByName("page1", "page1 param")
//带回调跳转,在目标页关闭后获取返回信息
this.navPathStack.pushPathByName("page1", "page1 param",(popInfo)=>{
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
})
//跳转并获取跳转结果信息
this.navPathStack.pushDestination({name:"page1",param:"page1 param"})
.then(()=>{
console.info('success');
})
.catch((err:BusinessError)=>{
console.info(`${err.code} - ${err.message}`);
}) //替换当前页面
this.navPathStack.replacePath({ name: "page1", param: "page1 param" }) //返回前一个页面
this.navPathStack.pop()
//返回到指定页面
this.navPathStack.popToName("page1") //删除栈中所有name=page1的页面
this.navPathStack.removeByName("page1")
//删除栈中指定索引的页面
this.navPathStack.removeByIndexes([1,2]) //获取page1页面的参数
this.navPathStack.getParamByName("page1")
//所有栈中索引1的页面参数
this.navPathStack.getParamByIndex(1)
//所有page1页面的索引集合
this.navPathStack.getIndexByName("page1")

子页面

子页面有容器 NavDestination 包裹,可以设置生命周期,独立的标题栏,菜单栏等属性,使用方法与navigation相同,其中mode属性可以指定页面类型。

页面类型:

  1. 标准类型:mode为NavDestinationMode.STANDARD,为默认类型,生命周期跟随其在NavPathStack页面栈中的位置变化而改变。
  2. 弹窗类型:mode为NavDestinationMode.DIALOG,显示为透明窗体,显示和消失时不会影响下层标准类型页面的显示和生命周期。

页面生命周期

Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。

● aboutToAppear和aboutToDisappear是自定义组件的生命周期

● OnAppear和OnDisappear是组件的通用生命周期

● 其余六个生命周期为NavDestination独有

@Component
export struct PageTwo {
@Consume('navPathStack') navPathStack: NavPathStack build() {
NavDestination() {
Column() {
Text("page2").geometryTransition("text2")
}.width('100%').height('100%')
}.title("Page2")
}
}

路由拦截

NavPathStack提供了setInterception方法,用于设置Navigation页面跳转拦截回调。该方法需要传入一个NavigationInterception对象。

NavigationInterception包含三个回调函数

  1. willShow:页面跳转前回调,允许操作栈,在当前跳转生效。
  2. didShow:页面跳转后回调,在该回调中操作栈会在下一次跳转生效。
  3. modeChange:Navigation单双栏显示状态发生变更时触发该回调。

    无论是哪个回调,在进入回调时页面栈都已经发生了变化。
this.navPathStack.setInterception({
willShow: (_from, _to, _operation, _animated) => {
if (typeof _to === "object") {
let target = _to as NavDestinationContext
if (target.pathInfo.name == "page1") {
target.pathStack.pop()
target.pathStack.pushPath({ name: "page2" })
}
}
}
})

本文的技术设计和实现都是基于作者工作中的经验总结,如有错误,请留言指正,谢谢。

HarmonyOS Next 入门实战 - 导航框架:页面路由、组件导航(Navigation)的更多相关文章

  1. 【DRF框架】路由组件

    视图组件涉及的路由补充: from rest_framework.viewsets import ViewSetMixin 对路由进行了重新的分发,重写了as_view() 方法,重新封装了请求方法 ...

  2. 零基础入门 实战mpvue2.0多端小程序框架

    第1章 课程快速预览(必看!!!)在这一章节中,老师讲带领你快速预览课程整体.其中,涉及到为什么要做这么一门实战课程.制作一个小程序的完整流程是怎么样的,以及如何做项目的技术选型. 第2章 30 分钟 ...

  3. 【Flutter学习】页面跳转之路由及导航

    一,概述 移动应用通常通过成为‘屏幕’或者‘页面’的全屏元素显示其内容,在Flutter中,这些元素统称为路由,它们由导航器Navigator组件管理.导航器管理一组路由Route对象,并提供了管理堆 ...

  4. 《React后台管理系统实战 :二》antd左导航:cmd批量创建子/目录、用antd进行页面布局、分离左导航为单独组件、子路由、动态写左导航、css样式相对陷阱

    一.admin页面布局及路由创建 0)cmd批量创建目录及子目录 //创建各个目录,及charts和子目录bar md home category product role user charts\b ...

  5. 手动搭建I/O网络通信框架2:Socket和ServerSocket入门实战,实现单聊

    第一章:手动搭建I/O网络通信框架1:Socket和ServerSocket入门实战,实现单聊 在第一章中运用Socket和ServerSocket简单的实现了网络通信.这一章,利用BIO编程模型进行 ...

  6. [Alibaba-ARouter] 简单好用的Android页面路由框架

    开发一款App,总会遇到各种各样的需求和业务,这时候选择一个简单好用的轮子,就可以事半功倍 前言 Intent intent = new Intent(mContext, XxxActivity.cl ...

  7. net Core 入门实战

    Asp.net Core 入门实战   Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个源码合集,方便一次性Clone 目录 快速入门 安 ...

  8. Blazor 路由及导航开发指南

    翻译自 Waqas Anwar 2021年4月2日的文章 <A Developer's Guide To Blazor Routing and Navigation> [1] 检查传入的请 ...

  9. Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署

    [注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...

  10. 快速入门系列--WebAPI--03框架你值得拥有

    接下来进入的是俺在ASP.NET学习中最重要的WebAPI部分,在现在流行的互联网场景下,WebAPI可以和HTML5.单页应用程序SPA等技术和理念很好的结合在一起.所谓ASP.NET WebAPI ...

随机推荐

  1. ASP.NET Core – Work with X509

    前言 这篇主要是说如何用 ASP.NET Core 读写系统里的证书 Store 和创建一个证书, 还有使用证书做加密, 解密, 签名. 主要参考: C#数字证书编程总结 (读写证书 Store) E ...

  2. 字节跳动的多平台绽放秘诀 | Flutter 开发者故事

    字节跳动旗下运营着一系列成功的用户产品.企业应用以及服务,覆盖信息.教育.娱乐等不同领域.随着产品阵容的不断发展,传统的原生双平台开发已经难以满足团队更高效.更灵活.更精美,以及更多样的产品研发需求. ...

  3. @Primary ,@Qualifier ,@Autowired ,@Resource作用与区别

    首先阐述 @Autowired 和 @Resource 的区别 @Resource 是JDK自带的注解 可以按名称注入也可以按类型注入,默认是按名称注入,没有显式指定名称时,在spring容器中匹配与 ...

  4. kmemleak 和kasan 的区别

    kmemleak 和kasan 都是 Linux 内核中的一些工具和特性,用于帮助进行内存错误检测和修复.然而,它们之间有一些区别: 功能:kmemleak 用于检测内核中未释放的内存泄漏,它可以跟踪 ...

  5. 15 Transformer 框架概述

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  6. 为 KubeSphere 集群启用免费的泛域名 SSL 证书并实现证书自动更新和分发

    作者:scwang18,主要负责技术架构,在容器云方向颇有研究. 前言 KubeSphere 集群默认安装的证书是自签发证书,浏览器访问访问会发出安全提醒.本文记录了利用 let's encrytp ...

  7. jenkin配置pytest+appium+allure持续集成环境

    首先配置项目: 这里建议使用自定义工作空间,可以避免git忽略提交得文件再被拉取到本地时不存在,导致得一些问题(因为有些配置文件可能不想提交到github,所以这样配置更合理一些,哈哈) git配置: ...

  8. C++ 简易消息循环

    前言 本文将向大家介绍如何使用 C++ 的标准库实现一个异步和并发编程中都非常重要的编程模式:消息循环(Event Loop).尽管市面上存在不少库也提供了同样的功能,但有时候出于一些原因,我们并不想 ...

  9. Nuxt.js 应用中的 imports:sources 事件钩子详解

    title: Nuxt.js 应用中的 imports:sources 事件钩子详解 date: 2024/10/27 updated: 2024/10/27 author: cmdragon exc ...

  10. SSAS部署失败方法总结

    最近在自学SSAS,从最简单的入手,却频频遇到问题,为了以后在学习过程中能更快的进行问题的定位,所以在此将遇到的问题以及解决方案进行记录 Q1:数据源"Adventure Works DW2 ...