一、路由Router
页面路由指在应用程序中实现不同页面之间的跳转和数据传递。页面路由包含页面跳转和页面 返回。
1、页面跳转
Router模块提供了两种跳转模式,分别是pushUrl和replaceUrl。
- pushUrl:目标页面不会替换当前页,而是压入页面栈。
- replaceUrl:目标页面会替换当前页,并销毁当前页。
//替换当前页面
router.replaceUrl({
url: FieldSingPage
})
//跳转新页面
router.pushUrl({
url: FieldSingPage
})
//跳转新页面并传参
router.pushUrl({
url: HouseSearchPage,
params: {
trade: this.trade
}
})
2、页面返回
当用户在一个页面完成操作后,通常需要返回到上一个页面或者指定页面,这就需要用到页面返回功能。
返回上一个页面
这种方式会返回到上一个页面,即上一个页面在页面栈中的位置。
router.back()
//返回上一页,并传递参数
router.back({
url:"",
params: {
verificationCode: this.verificationCode
}
})
返回指定页面
这种方式可以返回到指定页面,需要指定目标页面的路径。
router.back({
url: 'pages/FieldSingPage'
});
3、接受页面传递过来的参数
在跳转的新页面或者返回页面的指定页面接收传递过来的参数,通过router.getParams()获取到传递过来的所有参数,通过 key 值获取对应的参数数据
onPageShow(): void {
//接收验证码页面返回的验证码
let params = router.getParams() as Record<string, string>
if (params) {
this.smsCode = params["verificationCode"]
//验证码回到登录页调用登录方法
this.loginAction()
}
4、在module.json5中配置页面路径文件
使用 router跳转到某个页面需要在 module.json5中配置页面路径
{
"module": {
...
... //其他属性
...
"pages": "$profile:main_pages"
}
}
这里可以在resources/base/profile新建文件main_pages.json 文件,在此文件中配置页面路径。
{
"src": [
"pages/Index",
"pages/login/LoginPage",
"pages/house/HouseSearchPage",
"pages/house/HouseDetailsPage",
"pages/WoodenFishGame",
"pages/house/AddHousePage",
]
}
二、组件导航 Navigation
组件导航(Navigation)主要用于实现页面间以及组件内部的页面跳转,支持在不同组件间传递跳转参数,提供灵活的跳转栈操作,从而更便捷地实现对不同页面的访问和复用。Navigation组件主要包含导航页和子页。
Navigation路由相关的操作都是基于页面栈NavPathStack提供的方法进行,每个Navigation都需要创建并传入一个NavPathStack对象,用于管理页面。
1、导航页
导航页是一般是持续的入口页面,使用导航组件Navigation作为主页面的根容器,传递NavPathStack参数,
通过NavPathStack对象来控制页面的页面跳转、页面返回、页面替换、参数获取等功能
@Entry
@Component
struct Index {
// 创建一个页面栈对象并传入Navigation
pageStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageStack) {
//页面组件
}
}
}
页面跳转
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.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相关接口去实现页面返回功能。
// 返回到上一页
this.pageStack.pop();
// 返回到上一个PageOne页面
this.pageStack.popToName("PageOne");
// 返回到索引为1的页面
this.pageStack.popToIndex(1);
// 返回到根首页(清除栈中所有页面)
this.pageStack.clear();
页面替换
NavPathStack通过Replace相关接口去实现页面替换功能。
// 将栈顶页面替换为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.');
})
2、子页面
NavDestination是Navigation子页面的根容器,用于承载子页面的一些特殊属性以及生命周期等。
获取Navigation页面传递到子页面的参数
NavDestination子页第一次创建时会触发onReady回调,可以获取此页面对应的参数。
@Builder
export function AddFieldPageBuilder() {
AddFieldPage()
}
@Component
struct AddFieldPage {
pathStack: NavPathStack | undefined = undefined;
pageParam: string = '';
build() {
NavDestination() {
...
}.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
this.pageParam = context.pathInfo.param as string;
})
}
}
其他业务场景,可以通过主动调用NavPathStack的Get相关接口去获取指定页面的参数。
// 获取栈中所有页面name集合
this.pageStack.getAllPathName();
// 获取索引为1的页面参数
this.pageStack.getParamByIndex(1);
// 获取PageOne页面的参数
this.pageStack.getParamByName("PageOne");
// 获取PageOne页面的索引集合
this.pageStack.getIndexByName("PageOne");
子页面的配置
每个子页也需要配置到系统配置文件route_map.json中
{
"module": {
...
... //其他属性
...
"routerMap": "$profile:route_map"
}
}
在resources/base/profile新建文件route_map.json 文件,在此文件中配置页面信息,pageSourceFile是页面路径,buildFunction表示页面的 builder方法名称。
{
"routerMap": [
{
"name": "AddFieldPage",
"pageSourceFile": "src/main/ets/pages/field/AddFieldPage.ets",
"buildFunction": "AddFieldPageBuilder",
"data": {
"description": "新增外勤记录"
}
},
{
"name": "SelectBuildingPage",
"pageSourceFile": "src/main/ets/pages/house/SelectBuildingPage.ets",
"buildFunction": "SelectBuildingPageBuilder",
"data": {
"description": "选择楼盘"
}
}
]
}
三、Router切换Navigation
Router切换Navigation主要需要主要以下几点,页面配置和生命周期有点区别,Navigation具有更强的功能和自定义能力,目前最新版本的 api中已经废弃Router相关方法,推荐使用Navigation组件作为应用的路由框架。
1、页面配置
Router和Navigation都需要在配置文件中配置页面路径、信息,Navigation是需要配置子页面信息。
- Router中每一个页面都需要在main_page.json中声明
// main_page.json
{
"src": [
"pages/Index",
"pages/pageOne",
"pages/pageTwo"
]
}
- Navigation每个子页也需要配置到系统配置文件route_map.json中
// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"}
// route_map.json
{
"routerMap": [
{
"name": "pageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "this is pageOne"
}
}
]
}
2、路由操作
1、Router通过@ohos.router模块提供的方法来操作页面;
2、Navigation通过页面栈对象NavPathStack提供的方法来操作页面,需要创建一个栈对象并传入Navigation中。
3、生命周期
Router页面主要有以下四个生命周期:
// 页面创建后挂树的回调
aboutToAppear(): void {
}
// 页面销毁前下树的回调
aboutToDisappear(): void {
}
// 页面显示时的回调
onPageShow(): void {
}
// 页面隐藏时的回调
onPageHide(): void {
}
Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。
- aboutToAppear:在创建自定义组件后,执行其build()函数之前执行(NavDestination创建之前),允许在该方法中改变状态变量,更改将在后续执行build()函数中生效。
- onWillAppear:NavDestination创建后,挂载到组件树之前执行,在该方法中更改状态变量会在当前帧显示生效。
- onAppear:通用生命周期事件,NavDestination组件挂载到组件树时执行。
- onWillShow:NavDestination组件布局显示之前执行,此时页面不可见(应用切换到前台不会触发)。
- onShown:NavDestination组件布局显示之后执行,此时页面已完成布局。
- onActive:NavDestination处于激活态(处于栈顶可操作,且上层无特殊组件遮挡)触发。
- onWillHide:NavDestination组件触发隐藏之前执行(应用切换到后台不会触发)。
- onInactive:NavDestination组件处于非激活态(处于非栈顶不可操作,或处于栈顶时上层有特殊组件遮挡)触发。
- onHidden:NavDestination组件触发隐藏后执行(非栈顶页面push进栈,栈顶页面pop出栈或应用切换到后台)。
- onWillDisappear:NavDestination组件即将销毁之前执行,如果有转场动画,会在动画前触发(栈顶页面pop出栈)。
- onDisappear:通用生命周期事件,NavDestination组件从组件树上卸载销毁时执行。
- aboutToDisappear:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。
@Component
struct PageOne {
aboutToDisappear() {
}
aboutToAppear() {
}
build() {
NavDestination() {
// ...
}
.onWillAppear(() => {
})
.onAppear(() => {
})
.onWillShow(() => {
})
.onShown(() => {
})
.onWillHide(() => {
})
.onHidden(() => {
})
.onWillDisappear(() => {
})
.onDisAppear(() => {
})
}
}