HarmonyOS 页面路由Router切换组件导航Navigation_harmonyos router
一、路由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 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@Componentstruct 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相关接口去实现页面替换功能。
// 将栈顶页面替换为PageOnethis.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:自定义组件析构销毁之前执行,不允许在该方法中改变状态变量。
@Componentstruct PageOne { aboutToDisappear() { } aboutToAppear() { } build() { NavDestination() { // ... } .onWillAppear(() => { }) .onAppear(() => { }) .onWillShow(() => { }) .onShown(() => { }) .onWillHide(() => { }) .onHidden(() => { }) .onWillDisappear(() => { }) .onDisAppear(() => { }) }}