此文章仅供学习,不作其他用途。
如有侵权,请联系删除。
欢迎批评指正!!! 谢谢!!!
Navigation
Navigation组件是路由导航的根视图容器,一般情况下作为根容器使用。
一、 使用配置文件进行页面跳转
1. 创建一个根页面视图 NavPathStackDemo.ets
代码如下:
@Entry
@Preview
@Component
struct NavPathStackDemo {
pageInfos: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageInfos) {
Column() {
Button('pushPath')
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPath({ name: 'pageOne' })
})
}
}
}
}
注意:
@Entry装饰器修饰的页面,需要在main_pages.json文件中引用,否则会报错。@Preview装饰器是可以在模拟器中预览该页面。可以不写。@Component装饰器是标配,不说了。
2. 写子页面PageOne.ets
代码如下:
@Builder
export function PageOneBuilder(name: string, param: object) {
PageOne();
}
@Component
struct PageOne {
pageInfos: NavPathStack = new NavPathStack();
build() {
NavDestination() {
Column() {
Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
}
}
.title('PageOne')
}
}
PageOneBuilder函数是需要注意的。使用@Builder装饰器。别忘了export关键字
3. 配置文件
在路径
src/main/resources/base/profile文件夹下,配置route_map.json文件,代码如下:
{
"routerMap": [
{
"name": "pageOne",
"pageSourceFile": "src/main/ets/view/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "this is pageOne"
}
}
]
}
注意:
name: 对应的就是 跳转页面时写的 this.pageInfos.pushPath({ name: 'pageOne' })pageSourceFile: 对应的是需要跳转的页面的路径buildFunction: 对应的是 子页面中 使用@Builder修饰的函数(创建子页面对象)- 'data': 可写可不写
4. 在工程文件中配置route_map.json文件
找到 工程配置文件 module.json5文件, 在 module里边配置 routerMap属性,如下所示:
{
"module": {
...
"routerMap": "$profile:route_map"
}
}
接下来,就可以运行程序,测试Navigation的跳转效果了。
5. onReady的使用
场景:如果在PageOne页面中,继续跳转下一个页面PageTwo
PageTwo.ets代码如下:
@Builder
export function PageTwoBuilder(name: string) {
PageTwo();
}
@Component
export struct PageTwo {
pathStack: NavPathStack = new NavPathStack();
build() {
NavDestination() {
Column() {
Text('Page Two')
Button('Go To Page Three!', {type: ButtonType.Capsule})
.onClick(() => {
this.pathStack.pushPath({ name: 'pageThree'})
})
}
}
}
}
在route_map.json文件中配置如下:
{
"name": "pageTwo",
"pageSourceFile": "src/main/ets/view/PageTwo.ets",
"buildFunction": "PageTwoBuilder"
},
运行程序,当点击 PageOne页面中的pushPathByName按钮跳转PageTwo页面时,会没有反应,无法进行跳转。这时就需要用到onReady。
先来看一下官方解释:

onReady回调函数中有一个 NavDestinationContext参数,可以通过这个参数拿到当前NavDestination所处的页面栈。
PageOne.ets中代码如下(部分代码已省略):
@Builder
export function PageOneBuilder(name: string, param: object) {
PageOne();
}
@Component
struct PageOne {
pageInfos: NavPathStack = new NavPathStack();
build() {
NavDestination() {
Column() {
Button('pushPathByName', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPathByName("pageTwo", null);
})
}
}
.title('PageOne')
.onReady((context: NavDestinationContext) => {
this.pageInfos = context.pathStack;
})
}
}
再次运行程序,点击pushPathByName按钮,可以看到跳转到PageTwo页面了。

二、 使用navDestination属性
1. 创建主页面NavPathStackDemoTwo.ets文件
代码如下:
import { MinePage } from '../view/MinePage';
@Entry
@Preview
@Component
struct NavPathStackDemoTwo {
@Provide('pathStack') pageInfos: NavPathStack = new NavPathStack();
@Builder
PageTo(name: string) {
if (name === 'mine_page') {
MinePage();
}
}
build() {
Navigation(this.pageInfos) {
Column() {
Button('Go to mine page!')
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPath({ name: 'mine_page' })
})
}
}
.navDestination(this.PageTo)
}
}
注意:
navPathStack变量使用的是@Provide('xxx)修饰
@Provide(xxx)修饰的变量:会将该变量也就是navPathStack传递给跳转后的后代组件
而后代组件在获取时,需要使用@Consume来修饰,后边会有代码体现并讲解@Consume。
navDestination(builder: (name: string, param: unknown) => void): NavigationAttribute;
Set builder for user-defined NavDestination component.
翻译之后:用户自定义 NavDestination 组件的集合构造器
需要传入一个自定义的集合构造器 builder,也就是上边代码中使用 @Builder修饰的PageTo, 可以看到需要传入一个name的形参,param不是必传
注意: 这里的name 就是通过 this.pageInfos.pushPath({ name: 'mine_page' }) 中的name参数传入,
在PageTo内部通过对name值的匹配来控制需要做的事情。
2. 创建后代组件MinePage.ets
代码如下:
@Component
export struct MinePage {
@Consume pathStack: NavPathStack;
build() {
NavDestination() {
Column() {
Text('Mine Page')
Button('跳转到设置页面')
.onClick(() => {
this.pathStack.pushPathByName('settingPage', null);
})
}
.width('100%')
.height('100%')
.backgroundColor('#f1f3f5')
}
.title('我的')
.backgroundColor('#f1f3f5')
}
}
运行程序,点击按钮,则会跳转到settingPage所指向的SettingPage页面。依然是在route_map.json中配置。
有三点需要注意的地方:
-
@Consume: 通过@Consume装饰器在后代组件中拿到祖代组件传递过来的路由栈数据。 -
@Consume pathStack: NavPathStack;: 其中的pathStack变量命名需要和祖代组件中@Provide(xxx)中的xxx保持一致的命名。 - 这里不再使用
onReady去获取当前路由栈信息
在SettingPage页面如果还需要跳转到 更下层的页面,依然可以使用@Consume修饰的变量xxx,获取到祖代传递过来的路由栈数据。
SettingPage代码如下:
@Builder
export function SettingPageBuilder() {
SettingPage();
}
@Entry
@Component
export struct SettingPage {
@Consume pathStack: NavPathStack;
build() {
NavDestination() {
Column() {
Text('设置页面---')
Button('测试', { type: ButtonType.Capsule })
.onClick(() => {
this.pathStack.pushPathByName('pageThree', null);
})
}
.width('100%')
.height('100%')
}
}
}