Navigation 是路由导航的根视图容器,一般作为页面(@Entry)的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。一次开发,多端部署场景下,Navigation组件能够自动适配窗口显示大小,在窗口较大的场景下自动切换分栏展示效果。
TypeScript
Navigation() {
// ...
}
.mode(NavigationMode.Auto) // 自适应
.mode(NavigationMode.Split) // 分栏
.mode(NavigationMode.Stack) // 单栏
Navigation组件主要包含导航页和子页。导航页由标题栏(包含菜单栏)、内容区和工具栏组成,可以通过hideNavBar属性进行隐藏,导航页不存在路由栈中,与子页,以及子页之间可以通过路由操作进行切换。在API version 9上,Navigation需要配合NavRouter组件实现页面路由。从API version 10开始,更推荐使用NavPathStack实现页面路由。
显示模式
自适应模式
Navigation组件默认为自适应模式,此时mode属性为NavigationMode.Auto。自适应模式下,当页面宽度大于等于一定阈值( API version 9及以前:520vp,API version 10及以后:600vp )时,Navigation组件采用分栏模式,反之采用单栏模式。
单页面模式
单页面模式适用于窄屏设备,发生路由跳转时,整个页面都会被替换。
分栏模式
分栏模式适用于宽屏设备 ,分为左右两部分,发生路由跳转时,只有右边子页会被替换。
路由操作
Navigation路由相关的操作都是基于导航控制器 NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,用于管理页面。Navigation中的NavDestination页面存在于NavPathStack中,以栈的结构管理,称为路由栈。
TypeScript
@Entry
@Component
struct Index {
// 创建一个导航控制器对象并传入Navigation
pageStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageStack) {
}
.title('Main')
}
}
页面跳转
NavPathStack通过Push相关的接口去实现页面跳转的功能,主要分为以下三类:
普通跳转
通过页面的name去跳转,并可以携带param。
TypeScript
this.pageStack.pushPath({ name: "PageOne", param: "PageOne Param" });
this.pageStack.pushPathByName("PageOne", "PageOne Param");
带返回回调的跳转
跳转时添加onPop回调,能在页面出栈时获取返回信息,并进行处理。
TypeScript
this.pageStack.pushPathByName('PageOne', "PageOne Param", (popInfo) => {
console.log('Pop page name is: ' + popInfo.info.name + ', result: ' + JSON.stringify(popInfo.result));
});
带错误码的跳转
跳转结束会触发异步回调,返回错误码信息。
TypeScript
this.pageStack.pushDestination({name: "PageOne", param: "PageOne Param"})
.catch((error: BusinessError) => {
console.error(`Push destination failed, error code = ${error.code}, error.message = ${error.message}.`);
}).then(() => {
console.info('Push destination succeed.');
});
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.');
});
页面返回
NavPathStack通过Pop相关接口去实现页面返回功能。
TypeScript
// 返回到上一页
this.pageStack.pop();
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne");
// 返回到索引为1的页面
this.pageStack.popToIndex(1);
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear();
页面替换
NavPathStack通过Replace相关接口去实现页面替换功能。
TypeScript
// 将栈顶页面替换为PageOne
this.pageStack.replacePath({ name: "PageOne", param: "PageOne Param" });
this.pageStack.replacePathByName("PageOne", "PageOne Param");
// 带错误码的替换,跳转结束会触发异步回调,返回错误码信息
this.pageStack.replaceDestination({name: "PageOne", param: "PageOne Param"})
.catch((error: BusinessError) => {
console.error(`Replace destination failed, error code = ${error.code}, error.message = ${error.message}.`);
}).then(() => {
console.info('Replace destination succeed.');
})
页面删除
NavPathStack通过Remove相关接口去实现删除路由栈中特定页面的功能。
TypeScript
// 删除栈中name为PageOne的所有页面
this.pageStack.removeByName("PageOne");
// 删除指定索引的页面
this.pageStack.removeByIndexes([1, 3, 5]);
// 删除指定id的页面
this.pageStack.removeByNavDestinationId("1");
移动页面
NavPathStack通过Move相关接口去实现移动路由栈中特定页面到栈顶的功能。
TypeScript
// 移动栈中name为PageOne的页面到栈顶
this.pageStack.moveToTop("PageOne");
// 移动栈中索引为1的页面到栈顶
this.pageStack.moveIndexToTop(1);
参数获取
NavDestination子页第一次创建时会触发onReady回调,可以获取此页面对应的参数。
TypeScript
@Component
struct Page01 {
pathStack: NavPathStack | undefined = undefined;
pageParam: string = '';
build() {
NavDestination() {
// ...
}.title('Page01')
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
this.pageParam = context.pathInfo.param as string;
})
}
}
NavDestination组件中可以通过设置onResult接口,接收返回时传递的路由参数。
TypeScript
class NavParam {
desc: string = 'navigation-param'
}
@Component
struct DemoNavDestination {
// ...
build() {
NavDestination() {
// ...
}
.onResult((param: Object) => {
if (param instanceof NavParam) {
console.log('TestTag', 'get NavParam, its desc: ' + (param as NavParam).desc);
return;
}
console.log('TestTag', 'param not instance of NavParam');
})
}
}
其他业务场景,可以通过主动调用NavPathStack的Get相关接口去获取指定页面的参数。
TypeScript
// 获取栈中所有页面name集合
this.pageStack.getAllPathName();
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1);
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne");
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne");
路由拦截
NavPathStack提供了setInterception方法,用于设置Navigation页面跳转拦截回调。该方法需要传入一个NavigationInterception对象,该对象包含三个回调函数:

无论是哪个回调,在进入回调时路由栈都已经发生了变化。
开发者可以在willShow回调中通过修改路由栈来实现路由拦截重定向的能力。
TypeScript
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);
}
}
})