组件导航(Navigation)主要用于实现页面间以及组件内部的页面跳转,支持在不同组件间传递跳转参数,提供灵活的跳转栈操作,从而更便捷地实现对不同页面的访问和复用。本文将从组件导航(Navigation)的显示模式、路由操作、子页面管理、跨包跳转以及跳转动效等几个方面进行详细介绍。
[Navigation]是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。[一次开发,多端部署]场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。
Navigation组件主要包含导航页和子页。导航页由标题栏(包含菜单栏)、内容区和工具栏组成,可以通过[hideNavBar]属性进行隐藏,导航页不存在页面栈中,与子页,以及子页之间可以通过路由操作进行切换。
在API Version 9上,Navigation需要配合[NavRouter]组件实现页面路由。从API Version 10开始,更推荐使用[NavPathStack]实现页面路由。
设置页面显示模式
Navigation组件通过mode属性设置页面的显示模式。
-
自适应模式
Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。
Navigation() { // ... } .mode(NavigationMode.Auto)
-
单页面模式
图1 单页面布局示意图
将mode属性设置为NavigationMode.Stack,Navigation组件即可设置为单页面显示模式。
Navigation() { // ... } .mode(NavigationMode.Stack) ts
-
分栏模式
图2 分栏布局示意图
将mode属性设置为NavigationMode.Split,Navigation组件即可设置为分栏显示模式。
@Entry @Component struct NavigationExample { @State TooTmp: ToolbarItem = {'value': "func", 'icon': "./image/ic_public_highlights.svg", 'action': ()=> {}} @Provide('pageInfos') pageInfos: NavPathStack = new NavPathStack() private arr: number[] = [1, 2, 3]; @Builder PageMap(name: string) { if (name === "NavDestinationTitle1") { pageOneTmp() } else if (name === "NavDestinationTitle2") { pageTwoTmp() } else if (name === "NavDestinationTitle3") { pageThreeTmp() } } build() { Column() { Navigation(this.pageInfos) { TextInput({ placeholder: 'search...' }) .width("90%") .height(40) .backgroundColor('#FFFFFF') List({ space: 12 }) { ForEach(this.arr, (item:number) => { ListItem() { Text("Page" + item) .width("100%") .height(72) .backgroundColor('#FFFFFF') .borderRadius(24) .fontSize(16) .fontWeight(500) .textAlign(TextAlign.Center) .onClick(()=>{ this.pageInfos.pushPath({ name: "NavDestinationTitle" + item}) }) } }, (item:number) => item.toString()) } .width("90%") .margin({ top: 12 }) } .title("主标题") .mode(NavigationMode.Split) .navDestination(this.PageMap) .menus([ {value: "", icon: "./image/ic_public_search.svg", action: ()=> {}}, {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}}, {value: "", icon: "./image/ic_public_add.svg", action: ()=> {}} ]) .toolbarConfiguration([this.TooTmp, this.TooTmp, this.TooTmp]) } .height('100%') .width('100%') .backgroundColor('#F1F3F5') } } // PageOne.ets @Component export struct pageOneTmp { @Consume('pageInfos') pageInfos: NavPathStack; build() { NavDestination() { Column() { Text("NavDestinationContent1") }.width('100%').height('100%') }.title("NavDestinationTitle1") .onBackPressed(() => { const popDestinationInfo = this.pageInfos.pop() // 弹出路由栈栈顶元素 console.log('pop' + '返回值' + JSON.stringify(popDestinationInfo)) return true }) } } // PageTwo.ets @Component export struct pageTwoTmp { @Consume('pageInfos') pageInfos: NavPathStack; build() { NavDestination() { Column() { Text("NavDestinationContent2") }.width('100%').height('100%') }.title("NavDestinati