HarmonyOS--路由管理--组件导航 (Navigation)

文档中心

什么是组件导航 (Navigation) ?

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

2、Navigation组件适用于模块内和跨模块的路由切换,一次开发,多端部署场景。

3、通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果

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

5、Navigation组件主要包含​导航页(NavBar)和子页(NavDestination)

6、导航页由标题栏(Titlebar,包含菜单栏menu)、内容区(Navigation子组件)和工具栏(Toolbar)组成

7、其中导航页可以通过hideNavBar属性进行隐藏,导航页不存在页面栈中,导航页和子页,以及子页之间可以通过路由操作进行切换。

设置页面显示模式

自适应模式

Navigation() {
  ...
}
.mode(NavigationMode.Auto)

1、Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto

2、自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。

单页面模式

Navigation() {
  ...
}
.mode(NavigationMode.Stack)

分栏模式

Navigation() {
  ...
}
.mode(NavigationMode.Split)

设置标题栏模式

Mini模式

普通型标题栏,用于一级页面不需要突出标题的场景。

Navigation() {
  ...
}
.titleMode(NavigationTitleMode.Mini)

Full模式

强调型标题栏,用于一级页面需要突出标题的场景。

Navigation() {
  ...
}
.titleMode(NavigationTitleMode.Full)

设置菜单栏

1、菜单栏位于Navigation组件的右上角,开发者可以通过menus属性进行设置。

2、menus支持Array<NavigationMenuItem>和CustomBuilder两种参数类型

3、使用Array<NavigationMenuItem>类型时,竖屏最多支持显示3个图标,横屏最多支持显示5个图标,多余的图标会被放入自动生成的更多图标。

let TooTmp: NavigationMenuItem = {'value': "", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}

// resource中引入
let TooTmp: NavigationMenuItem = {'value': "", 'icon': "resources/base/media/ic_public_highlights.svg", 'action': ()=> {}} 
Navigation() {
  ...
}
.menus([TooTmp,
  TooTmp,
  TooTmp])

设置工具栏

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

let TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}}
let TooBar: ToolbarItem[] = [TooTmp,TooTmp,TooTmp]
Navigation() {
  ...
}
.toolbarConfiguration(TooBar)

子页面

1、NavDestination是Navigation子页面的根容器,用于承载子页面的一些特殊属性以及生命周期等

2、NavDestination可以设置独立的标题栏和菜单栏等属性,使用方法与Navigation相同。3、NavDestination也可以通过mode属性设置不同的显示类型,用于满足不同页面的诉求。

页面显示类型

标准类型

NavDestination组件默认为标准类型,此时mode属性为NavDestinationMode.STANDARD。标准类型的NavDestination的生命周期跟随其在NavPathStack页面栈中的位置变化而改变。

弹窗类型

NavDestination设置mode为NavDestinationMode.DIALOG弹窗类型,此时整个NavDestination默认透明显示。弹窗类型的NavDestination显示和消失时不会影响下层标准类型的NavDestination的显示和生命周期,两者可以同时显示。

// Dialog NavDestination
@Entry
@Component
 struct Index {
   @Provide('NavPathStack') pageStack: NavPathStack = new NavPathStack() // 声明一个页面栈

   @Builder
   PagesMap(name: string) {
     if (name == 'DialogPage') {
       DialogPage()
     }
   }

   build() {
     Navigation(this.pageStack) { // 传入页面栈
       Button('Push DialogPage')
         .margin(20)
         .width('80%')
         .onClick(() => {
           this.pageStack.pushPathByName('DialogPage', ''); // 拉起子页面
         })
     }
     .mode(NavigationMode.Stack)
     .title('Main')
     .navDestination(this.PagesMap) // 挂载子页面
   }
 }

 @Component
 export struct DialogPage {
   @Consume('NavPathStack') pageStack: NavPathStack;

   build() {
     NavDestination() { // 声明子页面
       ...
     }
     .backgroundColor('rgba(0,0,0,0.5)')
     .hideTitleBar(true)
     .mode(NavDestinationMode.DIALOG) // 弹窗类型
   }
 }

页面生命周期

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

2、其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期

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

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

5、剩下的六个生命周期为NavDestination独有(红色标注部分)

NavDestination声明周期

1、onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。

2、onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。

3、onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。

4、onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。

5、onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。

6、onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)

自定义组件生命周期

1、aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。

2、aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。

通用生命周期

1、onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行

2、onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。

页面监听和查询

页面状态监听

1、通过@ohos.arkui.observer提供的注册接口可以注册NavDestination生命周期变化的监听,使用方式如下:

observer.on('navDestinationUpdate', (info) => {
     console.info('NavDestination state update', JSON.stringify(info));
 });

2、也可以注册页面切换的状态回调,能在页面发生路由切换的时候拿到对应的页面信息NavDestinationSwitchInfo,并且提供了UIAbilityContext和UIContext不同范围的监听:

 // 在UIAbility中使用
 import observer from '@ohos.arkui.observer';
 import { UIContext } from '@ohos.arkui.UIContext';

 // callBackFunc 是开发者定义的监听回调函数
 function callBackFunc(info: observer.NavDestinationSwitchInfo) {}
 observer.on('navDestinationSwitch', this.context, callBackFunc);

 // 可以通过窗口的getUIContext()方法获取对应的UIContent
 uiContext: UIContext | null = null;
 observer.on('navDestinationSwitch', this.uiContext, callBackFunc);

页面信息查询

自定义组件提供queryNavDestinationInfo方法,可以在NavDestination内部查询到当前所属页面的信息,返回值为NavDestinationInfo,若查询不到则返回undefined。

import observer from '@ohos.arkui.observer';

 // NavDestination内的自定义组件
 @Component
 struct MyComponent {
   navDesInfo: observer.NavDestinationInfo | undefined

   aboutToAppear(): void {
     this.navDesInfo = this.queryNavDestinationInfo();
   }

   build() {
       Column() {
         Text("所属页面Name: " + this.navDesInfo?.name)
       }.width('100%').height('100%')
   }
 }

路由操作

1、Navigation路由相关的操作都是基于页面栈NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,

2、用于管理页面。主要涉及页面跳转、页面返回、页面替换、页面删除、参数获取、路由拦截等功能。

@Entry
@Component
struct Index {
  // 创建一个页面栈对象并传入Navigation
  pageStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.pageStack) {
    }
    .title('Main')
  }
}

页面跳转

1、普通跳转,通过页面的name去跳转,并可以携带param。

this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" })
this.pageStack.pushPathByName("PageOne", "PageOne Param")

2、带返回回调的跳转,跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理。

this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
});

3、带错误码的跳转,跳转结束会触发异步回调,返回错误码信息。

this.pageStack.pushDestinationByName('PageOne', "PageOne Param")
.catch((error: BusinessError) => {
    console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
}).then(() => {
console.error('Push destination succeed.');
});

页面返回

// 返回到上一页
this.pageStack.pop()
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne")
// 返回到索引为1的页面
this.pageStack.popToIndex(1)
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear()

页面替换

// 将栈顶页面替换为PageOne
this.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" })
this.pageStack.replacePathByName("PageOne", "PageOne Param")

页面删除

// 删除栈中name为PageOne的所有页面
this.pageStack.removeByName("PageOne")
// 删除指定索引的页面
this.pageStack.removeByIndexes([1,3,5])

参数获取

// 获取栈中所有页面name集合
this.pageStack.getAllPathName()
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1)
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne")
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne")

路由拦截

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

名称

描述

willShow

页面跳转前回调,允许操作栈,在当前跳转生效。

didShow

页面跳转后回调,在该回调中操作栈会在下一次跳转生效。

modeChange

Navigation单双栏显示状态发生变更时触发该回调。

例子

this.pageStack.setInterception({
  willShow: (from: NavDestinationContext | "navBar", to: NavDestinationContext | "navBar",
    operation: NavigationOperation, animated: boolean) => {
    if (typeof to === "string") {
      console.log("target page is navigation home page.");
      return;
    }
    // 将跳转到PageTwo的路由重定向到PageOne
    let target: NavDestinationContext = to as NavDestinationContext;
    if (target.pathInfo.name === 'PageTwo') {
      target.pathStack.pop();
      target.pathStack.pushPathByName('PageOne', null);
    }
  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/759317.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实现点击按钮导出页面pdf

在Vue 3 Vite项目中&#xff0c;你可以使用html2canvas和jspdf库来实现将页面某部分导出为PDF文档的功能。以下是一个简单的实现方式&#xff1a; 1.安装html2canvas和jspdf&#xff1a; pnpm install html2canvas jspdf 2.在Vue组件中使用这些库来实现导出功能&#xff1a;…

网线直连电脑可以上网,网线连tplink路由器上不了网

家里wifi网络连不上好几天了&#xff0c;用网线直连电脑可以上网&#xff0c;但网线连tplink路由器wan口上不了网&#xff0c;无Internet连接&#xff0c;网线连lan口可以电脑上网&#xff0c;手机上不了。 后来发现网线的主路由用的192.168.0.1&#xff0c;我的路由器wan口自…

在node环境使用MySQL

什么是Sequelize? Sequelize是一个基于Promise的NodeJS ORM模块 什么是ORM? ORM(Object-Relational-Mapping)是对象关系映射 对象关系映射可以把JS中的类和对象&#xff0c;和数据库中的表和数据进行关系映射。映射之后我们就可以直接通过类和对象来操作数据表和数据了, 就…

【大数据导论】大数据序言

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 目录 数据概念及类型及可用及组织形式数据概念数据…

golang项目基于gorm框架从postgre数据库迁移到达梦数据库的实践

一、安装达梦数据库 1、登录达梦数据库官网&#xff0c;下载对应系统版本的安装包。 2、下载地址为&#xff1a;https://www.dameng.com/list_103.html 3、达梦数据库对大小写敏感&#xff0c;在安装初始化数据库实例时建议忽略大小写&#xff1b;具体安装教程可参考以下博客: …

python办公自动化之pandas

用到的库&#xff1a;pandas 实现效果&#xff1a;创建一张空白的表同时往里面插入准备好的数据 代码&#xff1a; import pandas # 准备好要写入的数据&#xff0c;字典格式 data{日期:[7.2,7.3],产品型号:[ca,ce],成交量:[500,600]} dfpandas.DataFrame(data) # 把数据写入…

Java代码基础算法练习-计算被 3 或 5 整除数之和-2024.06.29

任务描述&#xff1a; 计算 1 到 n 之间能够被 3 或者 5 整除的数之和。 解决思路&#xff1a; 输入的数字为 for 循环总次数&#xff0c;每次循环就以当前的 i 进行 3、5 的取余操作&#xff0c;都成立计入总数sum中&#xff0c;循环结束&#xff0c;输出 sum 的值 代码示例&…

QT加载安装外围依赖库的翻译文件后翻译失败的现象分析:依赖库以饿汉式的形式暴露单例接口导致该现象的产生

1、前提说明 QtClassLibaryDll是动态库,QtWidgetsApplication4是应用程序。 首先明确:动态库以饿汉式的形式进行单例接口暴露; 然后,应用程序加载动态库的翻译文件并进行全局安装; // ...QTranslator* trans = new QTranslator();//qDebug() << trans->load(&quo…

大模型系列:提示词管理

既然大模型应用的编程范式是面向提示词的编程&#xff0c;需要建立一个全面且结构化的提示词库&#xff0c; 对提示词进行持续优化也是必不可少的&#xff0c;那么如何在大模型应用中更好的管理提示词呢&#xff1f; 1. 提示词回顾 提示词在本质上是向大型语言模型&#xff08…

​Chrome插件:React Developer Tools为React开发调试而生

React Developer Tools 是什么? 它是允许在Chrome和Firefox开发者工具中检查React组件层次结构的扩展插件。 插件源码下载 源码下载地址:GitHub - facebook/react-devtools at v3 下载完成以后执行红框中的代码,下载react-devtools 源码,源码如下图所示: 插件打包 当前n…

【C++】 ——【模板初阶】——基础详解

目录 1. 泛型编程 1.1 泛型编程的概念 1.2 泛型编程的历史与发展 1.3 泛型编程的优势 1.4 泛型编程的挑战 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 2.6 函数模板的特化 2.7 函数模板的使…

Linux CentOS 宝塔中禁用php8.2的eval函数详细图文教程

PHP_diseval_extension 这个方法是支持PHP8的, Suhosin禁用eval函数&#xff0c;不支持PHP8 一、安装 cd / git clone https://github.com/mk-j/PHP_diseval_extension.gitcd /PHP_diseval_extension/source/www/server/php/82/bin/phpize ./configure --with-php-config/ww…

美团校招机试 - 小美的平衡矩阵(20240309-T1)

题目来源 美团校招笔试真题_小美的平衡矩阵 题目描述 小美拿到了一个 n * n 的矩阵&#xff0c;其中每个元素是 0 或者 1。 小美认为一个矩形区域是完美的&#xff0c;当且仅当该区域内 0 的数量恰好等于 1 的数量。 现在&#xff0c;小美希望你回答有多少个 i * i 的完美…

C++操作系列(二):VSCode安装和配置C++开发环境

1. VSCode下载 进入VSCode的官网网页&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 下载相应的版本&#xff1a; 2. 安装VSCode 安装到指定位置&#xff1a; 一路下一步&#xff0c;直至安装完成&#xff1a; 3. 安装C插件 3.1. 安装C/C 点击扩展图标&…

linux上git的使用

目录 1.测试是否安装有git 2.下载项目到本地 3.三板斧 1.将代码放在创建的目录中 2.提交改动到本地 3.提交代码到远端 4.注意点 以及补充内容 1.测试是否安装有git 如果输入git --help 会显示下面一大串那么就是已经安装&#xff0c;否则需要自行手动安装 yum install g…

Elasticsearch开启认证|为ES设置账号密码|ES账号密码设置|ES单机开启认证|ES集群开启认证

文章目录 前言单节点模式开启认证生成节点证书修改ES配置文件为内置账号添加密码Kibana修改配置验证 ES集群开启认证验证 前言 ES安装完成并运行&#xff0c;默认情况下是允许任何用户访问的&#xff0c;这样并不安全&#xff0c;可以为ES开启认证&#xff0c;设置账号密码。 …

【Python从入门到进阶】59、Pandas库中Series对象的操作(二)

接上篇《58、Pandas库中Series对象的操作(一)》 上一篇我们讲解了Pandas库中Series对象的基本概念、对象创建和操作&#xff0c;本篇我们来继续学习Series对象的运算、函数应用、时间序列操作&#xff0c;以及Series的案例实践。 一、Series对象的运算 1. 数值型数据的算术运…

ElasticSearch索引架构与存储

关于ES官网的介绍: Elasticsearch provides near real-time search and analytics for all types of data. Whether you have structured or unstructured text, numerical data, or geospatial data, Elasticsearch can efficiently store and index it in a way that support…

详细介绍MySQL的索引(下)

索引的使用 同一条数据在未创建索引的情况下耗时&#xff1a; nick字段是未创建索引的 select * from t_user WHERE nick 邹丽;SHOW PROFILES; 耗时为&#xff1a; user_account字段创建了唯一索引 select * from t_user WHERE user_account 13781945844;SHOW PROFILES;…

基于Vue3 + Typescript 封装 Element-Plus 组件

1. 课程简介 项目地址 git clone https://gitee.com/childe-jia/my-message.git 背景: 该课程是基于Vue3 Typescript Vite构建, 教会大家封装Element-Plus组件 具备能力: 最新的 Vue3 及相关技术组件的设计思想大厂的开发模式/代码规范 技术: Vue3 首次渲染 / diff 算法 …