鸿蒙NEXT开发-Navigation组件导航
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下
如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识
专栏地址: https://blog.csdn.net/qq_56760790/category_12794123.html
鸿蒙next学习交流q群:767465523
目录
1. 基本介绍
2. 子组件
3. 接口
4. 设置页面显示模式
4.1 自适应模式
4.2 单页面模式
4.3 分栏模式
5. 设置标题栏模式
5.1 Mini模式标题栏
5.2 Full模式
6. 路由操作
6.1 初始化代码
6.2 页面跳转
6.3 页面返回
6.4 页面替换
6.5 页面删除
6.6 参数获取
7. 子页面
7.1 页面显示类型
7.2 页面生命周期
8. 小案例
9. 学习地址
1. 基本介绍
Navigation是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。一次开发,多端部署场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。
注意:页面路由推荐使用Navigation
Navigation的这种跳转方式耦合度较高,不适合大型的项目解耦开发。
2. 子组件
可以包含子组件。
从API Version 9开始,推荐与NavRouter组件配合NavDestination属性进行页面路由
@Entry
@Component
struct Index {
build() {
Navigation() {
NavRouter() {
Row() {
Button("去A页面")
}
.height(60)
NavDestination() {
Text("A页面内容")
}
.title("A页面")
}
NavRouter() {
Row() {
Button("去B页面")
}
.height(60)
NavDestination() {
Text("B页面内容")
}
.title("B页面")
}
}
.title("测试")
.titleMode(NavigationTitleMode.Mini)
}
}
从API Version 10开始,推荐使用NavPathStack配合NavDestination属性进行页面路由。
@Entry
@Component
struct Index {
@Provide
stackPath: NavPathStack = new NavPathStack() // 声明一个pathStack对象
@Styles
gridStyle () {
.height(100)
.borderRadius(10)
.backgroundColor(Color.Red)
.margin(10)
}
@Builder
getPageContent (name: string) {
if(name === "friend") {
// 渲染好友组件
Friend()
}
else if(name === "my") {
// 渲染我的组件
My()
}
else if(name === "connect") {
// 渲染联系人组件
Connect()
}
else if(name === "chat") {
// 渲染聊天组件
Chat()
}
}
build() {
// 绑定关系
Navigation(this.stackPath) {
// 四个导航 导航不同的页面
// 好友 我的 联系人 聊天
GridRow ({ columns: 2 }) {
GridCol() {
Text("好友")
.fontColor(Color.White)
}
.gridStyle()
.onClick(() => {
this.stackPath.pushPathByName("friend", null)
})
GridCol() {
Text("我的")
.fontColor(Color.White)
} .gridStyle()
.onClick(() => {
this.stackPath.pushPathByName("my", null)
})
GridCol() {
Text("联系人")
.fontColor(Color.White)
} .gridStyle()
.onClick(() => {
this.stackPath.pushPathByName("connect", null)
})
GridCol() {
Text("聊天")
.fontColor(Color.White)
} .gridStyle()
.onClick(() => {
this.stackPath.pushPathByName("chat", null)
})
}
}
.title("主页")
.titleMode(NavigationTitleMode.Mini)
.navDestination(this.getPageContent)
}
}
@Component
struct Friend {
@Consume
stackPath: NavPathStack
build() {
NavDestination() {
Text("好友组件")
Button("到我的").onClick((event: ClickEvent) => {
this.stackPath.replacePathByName("my", null)
})
}
.title("好友")
}
}
@Component
struct My {
build() {
NavDestination() {
Text("我的")
}
.title("我的")
}
}
@Component
struct Connect {
build() {
NavDestination() {
Text("联系人")
}
.title("联系人")
}
}
@Component
struct Chat {
build() {
NavDestination() {
Text("聊天")
}
.title("聊天")
}
}
3. 接口
Navigation()
绑定路由栈到Navigation组件。
Navigation(pathInfos: NavPathStack)
4. 设置页面显示模式
Navigation组件通过mode属性设置页面的显示模式。
分为以下三种:
1、自适应模式(默认)
2、单页面模式
3、分栏模式
4.1 自适应模式
Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。
Navigation() {
// ...
}
.mode(NavigationMode.Auto)
4.2 单页面模式
将mode属性设置为NavigationMode.Stack,Navigation组件即可设置为单页面显示模式。
Navigation() {
// ...
}
.mode(NavigationMode.Stack)
4.3 分栏模式
将mode属性设置为NavigationMode.Split,Navigation组件即可设置为分栏显示模式。
Navigation() {
// ...
}
.mode(NavigationMode.Split)
5. 设置标题栏模式
标题栏在界面顶部,用于呈现界面名称和操作入口,Navigation组件通过titleMode属性设置标题栏模式。
标题栏模式分为以下两种
Mini模式
Full模式
注意:设置标题直接用Navigation().title('标题')即可
5.1 Mini模式标题栏
普通型标题栏,用于一级页面不需要突出标题的场景。
Navigation() {
// ...
}
.titleMode(NavigationTitleMode.Mini)
5.2 Full模式
强调型标题栏,用于一级页面需要突出标题的场景。
Navigation() {
// ...
}
.titleMode(NavigationTitleMode.Full)
6. 路由操作
Navigation路由相关的操作都是基于页面栈NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,用于管理页面。主要涉及页面跳转、页面返回、页面替换、页面删除、参数获取、路由拦截等功能。
6.1 初始化代码
@Entry
@Component
struct Index {
// 创建一个页面栈对象并传入Navigation
pageStack: NavPathStack = new NavPathStack()
build() {
Navigation(this.pageStack) {
}.title('登录页面') // 设置标题
.titleMode(NavigationTitleMode.Full) // 设置标题栏模式
}
}
6.2 页面跳转
NavPathStack通过Push相关的接口去实现页面跳转的功能,主要分为以下三类:
- 普通跳转,通过页面的name去跳转,并可以携带param。
this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" })
this.pageStack.pushPathByName("PageOne", "PageOne Param")
- 带返回回调的跳转,跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理。
this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
});
- 带错误码的跳转,跳转结束会触发异步回调,返回错误码信息。
this.pageStack.pushDestinationByName('PageOne', "PageOne Param")
.catch((error: BusinessError) => {
console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
}).then(() => {
console.info('Push destination succeed.');
});
6.3 页面返回
NavPathStack通过Pop相关接口去实现页面返回功能。
// 返回到上一页
this.pageStack.pop()
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne")
// 返回到索引为1的页面
this.pageStack.popToIndex(1)
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear()
6.4 页面替换
NavPathStack通过Replace相关接口去实现页面替换功能。
// 将栈顶页面替换为PageOne
this.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" })
this.pageStack.replacePathByName("PageOne", "PageOne Param")
6.5 页面删除
NavPathStack通过Remove相关接口去实现删除页面栈中特定页面的功能。
// 删除栈中name为PageOne的所有页面
this.pageStack.removeByName("PageOne")
// 删除指定索引的页面
this.pageStack.removeByIndexes([1,3,5])
6.6 参数获取
NavPathStack通过Get相关接口去获取页面的一些参数。
// 获取栈中所有页面name集合
this.pageStack.getAllPathName()
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1)
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne")
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne")
7. 子页面
NavDestination是Navigation子页面的根容器,用于承载子页面的一些特殊属性以及生命周期等。NavDestination可以设置独立的标题栏和菜单栏等属性,使用方法与Navigation相同。NavDestination也可以通过mode属性设置不同的显示类型,用于满足不同页面的诉求。
7.1 页面显示类型
- 标准类型
NavDestination组件默认为标准类型,此时mode属性为NavDestinationMode.STANDARD。标准类型的NavDestination的生命周期跟随其在NavPathStack页面栈中的位置变化而改变。
- 弹窗类型
NavDestination设置mode为NavDestinationMode.DIALOG弹窗类型,此时整个NavDestination默认透明显示。弹窗类型的NavDestination显示和消失时不会影响下层标准类型的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() {
Stack({ alignContent: Alignment.Center }) {
Column() {
Text("Dialog NavDestination")
.fontSize(20)
.margin({ bottom: 100 })
Button("Close").onClick(() => {
this.pageStack.pop()
}).width('30%')
}
.justifyContent(FlexAlign.Center)
.backgroundColor(Color.White)
.borderRadius(10)
.height('30%')
.width('80%')
}.height("100%").width('100%')
}
.backgroundColor('rgba(0,0,0,0.5)')
.hideTitleBar(true)
.mode(NavDestinationMode.DIALOG)
}
}
7.2 页面生命周期
Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。
其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。
生命周期时序如下图所示:
- aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
- onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。
- onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行。
- onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
- onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。
- onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。
- onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
- onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
- onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。
- aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。
官方文档地址:文档中心
8. 小案例
从首页跳转到详情页面(用Navigation)
Index.ets
import Detail from './Detail'
import Mine from './Mine'
@Entry
@Component
struct Index {
@Provide pageStack: NavPathStack = new NavPathStack()
@Builder
PagesMap(name: string, param: Record<string, string>) {
if (name == 'Detail') {
Detail({ param: param['content'] })
}
if (name == 'Mine') {
Mine()
}
}
build() {
Navigation(this.pageStack) {
Button('跳转')
.margin(20)
.width('80%')
.onClick(() => {
this.pageStack.pushPathByName('Detail', new Object({ 'content': '详情页你好呀' }));
})
}
.title('首页')
.navDestination(this.PagesMap)
}
}
Detail.ets
@Component
export default struct Detail {
@Consume pageStack: NavPathStack
param: string = ''
build() {
NavDestination() {
Text(this.param)
Button("跳转我的页面").margin(20)
.width('80%').onClick(() => {
this.pageStack.replacePathByName("Mine", null)
})
}.title('详情页')
}
}
Mine.ets
@Component
export default struct Mine {
@Consume pageStack: NavPathStack
build() {
NavDestination() {
Text('我的')
Button("跳转详情页面").margin(20)
.width('80%').onClick(() => {
this.pageStack.replacePathByName("Detail", new Object({'content':'详情页你好'}))
})
}.title('我的')
}
}
9. 学习地址
全网首发鸿蒙NEXT星河版零基础入门到实战,2024年最新版,企业级开发!视频陆续更新中!_哔哩哔哩_bilibili