注:本章只是简单介绍一下其用法,详情请看官方文档:
Navigation:文档中心
1. Navigation:
Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(NavDestination的子组件),首页和非首页通过路由进行切换。
NavRouter :导航组件,默认提供点击响应处理,不需要开发者自定义点击事件逻辑。必须包含两个子组件,其中第二个子组件必须为NavDestination。
NavDestination: 作为子页面的根容器,用于显示Navigation的内容区。
1.1 Navigation + NavRouter + NavDestination实现组件跳转(API9)
Navigation内书写的是页面的内容,是Navigation实现页面跳转最外层的跟容器,如果嵌套NavRouter,NavRouter下需要嵌套两个子组件,第一个子组件自定义,点击可以跳转到第二个子组件,第二个必须为NavDestination包裹的子组件,用于显示跳转目标组件的内容。详情看代码:
@Entry
@Component
struct NavigationAPI9 {
build() {
Column() {
Navigation() {
Text('页面1')
NavRouter() {
// 只能写一个组件,写的多了,后面替换前面
Button('按钮1')
Button('按钮2')
NavDestination() {
Text('页面2')
NavRouter() {
Button('按钮3')
NavDestination() {
Text('页面3')
NavRouter() {
// .....
}
}
}
}
}
}
}
.height('100%')
.width('100%')
}
}
效果如下:
1.2. Navigation + NavDestination + NavPathStack 实现组件跳转(API10)
首先显示的页面需要用Navigation包裹,其内书写的为首页内容。可以为其设置toolbarConfiguration属性实现类似Tabs组件的效果,设置title设置标题,设置titleMode属性设置标题模式等等。
@State activeName: string = 'tab1'
build() {
Navigation() {
if (this.activeName === 'tab1') {
NavigationCase1() // 切换的组件
} else if (this.activeName === 'tab2') {
NavigationCase2() // 切换的组件
} else {
Text('123')
}
}
.height('100%')
.width('100%')
.toolbarConfiguration(this.tabBarBuilder) // 设置tabBar
.navDestination(this.navDestination) // 设置路由容器
.title(this.titleBuilder, {
backgroundColor: Color.Blue,
}) // 设置标题
.titleMode(NavigationTitleMode.Full) // 标题模式
.menus(this.NavigationMenus) // 顶部图标
.hideTitleBar(false) // 是否隐藏标题栏
.hideNavBar(false) // 是否隐藏导航栏, 隐藏Navigation的导航栏,包括标题栏、内容区和工具栏。
.backgroundColor(Color.Pink)
}
如果你想实现跳转,你需要为Navigation组件配置navDestination属性创建路由容器(或者说罗路由出口)。
NavDestination1与NavDestination2为跳转组件。
之后你需要配置NavPathStack页面栈进行跳转(你可以将其理解为控制器)
整体跳转思路,首先展示的为tab切换页,tab1、tab2、tab3, tab1可以通过跳转NavDestination1按钮跳转到name为NavDestination1的页面(看路由容器),到NavDestination1页面,可以通过按钮跳转NavDestination2跳转到页面NavDestination2,这里携带了param参数,到页面NavDestination2可以通过页面栈NavPathStack中的getParamByName进行接收。
注: 跳转的页面,必须由NavDestination组件包裹
详细demo代码:
//------------ NavigationCase主页面-----
import NavDestination1 from './components/NavDestination1'
import NavDestination2 from './components/NavDestination2'
import NavigationCase1 from './components/NavigationCase1'
import NavigationCase2 from './components/NavigationCase2'
@Entry
@Component
struct NavigationCase {
@State activeName: string = 'tab1'
// tabs
@Builder
tabBarBuilder() {
Row() {
ForEach(['tab1', 'tab2', 'tab3'], (item: string) => {
Column() {
Image($r('app.media.ic_public_message')).width(24).aspectRatio(1)
Text(item).fontColor(this.activeName === item ? '#ff00ff0f' : '#000')
}.onClick(() => {
this.activeName = item
})
})
}.width('100%').justifyContent(FlexAlign.SpaceAround)
}
// 标题
@Builder
titleBuilder() {
Row() {
Text('title').fontWeight(700)
}
.width('100%')
.justifyContent(FlexAlign.Center)
}
// 顶部icon
@Builder
NavigationMenus() {
Row() {
Image($r('app.media.ic_public_contacts_group'))
.width(24).aspectRatio(1)
Image($r('app.media.ic_public_contacts_group'))
.width(24)
.height(24)
Image($r('app.media.ic_public_contacts_group'))
.width(24)
.height(24)
}.width('100%').justifyContent(FlexAlign.SpaceAround)
}
// 路由容器
@Builder
navDestination(name: string) {
if (name === 'NavDestination2') {
NavDestination2()
} else if (name === 'NavDestination1') {
NavDestination1()
}
}
//路由栈, (控制跳转)
@Provide
navStack: NavPathStack = new NavPathStack()
build() {
Navigation(this.navStack) {
if (this.activeName === 'tab1') {
NavigationCase1()
} else if (this.activeName === 'tab2') {
NavigationCase2()
} else {
Text('123')
}
}
.height('100%')
.width('100%')
.toolbarConfiguration(this.tabBarBuilder) // 设置tabBar
.navDestination(this.navDestination) // 设置路由容器
.title(this.titleBuilder, {
backgroundColor: Color.Blue,
}) // 设置标题
.titleMode(NavigationTitleMode.Full) // 标题模式
.menus(this.NavigationMenus) // 顶部图标
.hideTitleBar(false) // 是否隐藏标题栏
.hideNavBar(false) // 是否隐藏导航栏, 隐藏Navigation的导航栏,包括标题栏、内容区和工具栏。
.backgroundColor(Color.Pink)
}
}
// ------------- NavigationCase1 : tab页面1 --------------
@Component
struct NavigationCase1 {
@Consume navStack: NavPathStack
build() {
Column() {
Text('tab1')
Button('跳转NavDestination1').onClick((event: ClickEvent) => {
this.navStack.pushPath({
name: 'NavDestination1'
})
})
}
}
}
export default NavigationCase1
// ------------- NavigationCase1 : tab页面2 --------------
@Component
struct NavigationCase2 {
build() {
Column() {
Text('tab2')
}
}
}
export default NavigationCase2
// -----------跳转页面1 -----------------
@Component
struct NavDestination1 {
@Consume navStack: NavPathStack
build() {
NavDestination() {
Column() {
Text('页面1')
Button('跳转NavDestination2').onClick(() => {
const param: Record<string, string> = {
'dec': '跳转NavDestination2'
}
this.navStack.pushPath({
name: 'NavDestination2',
param
})
})
}
}.title('页面1')
}
}
export default NavDestination1
// -----------跳转页面2 -----------------
import { promptAction } from '@kit.ArkUI'
@Component
struct NavDestination2 {
@Consume navStack: NavPathStack
aboutToAppear(): void {
promptAction.showDialog({
message: JSON.stringify(this.navStack.getParamByName('NavDestination2'))
})
}
build() {
NavDestination() {
Column() {
Text('页面2')
}
}.title('页面2').hideTitleBar(true)
}
}
export default NavDestination2
2. 页面跳转
通过NavPathStack控制页面路由,实现跳转,返回,移除页面栈等
2.1 普通跳转
普通跳转,通过页面的name去跳转,并可以携带param。
- this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" })
- this.pageStack.pushPathByName("PageOne", "PageOne Param")
2.2 带返回回调的跳转,跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理。
this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result))
});
2.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.');
});
3. 参数获取
// size: 获取页面栈大小
this.pageStack.size()
// 获取栈中所有页面name集合
// 获取【栈中】所有NavDestination页面的名称。
this.pageStack.getAllPathName()
// 获取【指定index】的NavDestination页面的参数信息。
this.pageStack.getParamByIndex(index)
// 获取全部name为PageOne的NavDestination页面的参数信息。
this.pageStack.getParamByName("PageOne")
// 获取全部name为PageOne的NavDestination页面的位置索引。
this.pageStack.getIndexByName("PageOne")
4. 页面返回、替换、删除
// 返回到上一页
this.pageStack.pop()
this.pageStack.removeByIndexes([this.pageStack.size-1])
// 返回到上一个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])