鸿蒙Next开发日记 Day11 - 如何把项目中的router修改为Navigation
早期入坑鸿蒙NEXT的小伙伴,使用的可能是router方式实现的页面跳转功能。
从API9之后,鸿蒙推出了Navigation方式进行页面跳转管理。
Navigation相比较router,封装了很多使用的功能,并提供了丰富的拓展方式。
Navigation是路由容器组件,一般作为首页的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,一次开发,多端部署场景。
通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式来呈现更好的标题和内容联动效果。
在不同尺寸的设备上,Navigation组件能够自适应显示大小,自动切换分栏展示效果。
先来看一下两者在配置方面的区别,如何修改。
router需要现在src/main/resources/base/profile/main_pages.json下面定义好每个页面。
比如
{ "src": [ "pages/Index", "pages/player/Player", "pages/home/media/EmbyEpisodeDetail" "pages/player/Player" ] }
而Navigation每个页面也是需要定义的,只是定义的位置和文件并不相同。
src/main/resources/base/profile/route_map.json
{ "routerMap": [ { "name": "EmbyEpisodeDetail", "pageSourceFile": "src/main/ets/pages/home/media/EmbyEpisodeDetail.ets", "buildFunction": "EmbyEpisodeDetailBuilder", "data": { "description": "EmbyEpisodeDetail" } }, { "name": "Player", "pageSourceFile": "src/main/ets/pages/player/Player.ets", "buildFunction": "PlayerBuilder", "data": { "description": "AvPlayer" } } ] }
同时需要在src/main/module.json5文件下面的module中,添加
"routerMap": "$profile:route_map",
整个文件的样式为
{ "module": { "name": "main", "type": "entry", "description": "$string:module_desc", "mainElement": "MainAbility", "deviceTypes": [ "phone", "tablet", "2in1" ], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", "routerMap": "$profile:route_map", "abilities": [ { "name": "MainAbility", "srcEntry": "./ets/mainability/MainAbility.ets", "description": "$string:ability_desc", "icon": "$media:startIcon", "label": "$string:ability_label", "startWindowIcon": "$media:startIcon", "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "action.system.home" ] } ] } ], "extensionAbilities": [ { "name": "MainBackupAbility", "srcEntry": "./ets/mainbackupability/MainBackupAbility.ets", "type": "backup", "exported": false, "metadata": [ { "name": "ohos.extension.backup", "resource": "$profile:backup_config" } ], } ], "requestPermissions": [ { "name": "ohos.permission.INTERNET", } ] } }
页面编写有什么不同
router上,页面使用@Entry与@Component进行修饰,内部开发通用页面开发方法即可。
@Entry @Component struct Index { build() { } }
Navigation的话,编写方法并不相同。
首相,通过前面提到的route_map,你需要创建相关的Builder才行。
@Builder export function PersonDetailPageBuilder(name: string, param: Object) { PersonDetailPage({ param: param as Record<string, Object> }) } @Component struct PersonDetailPage {}
其次,根导航页需要使用Navigation作为根节点,并传入用Provide注解后的NavPathStack用于全局使用。
@Provide('navPathStack') navPathStack:NavPathStack = new NavPathStack(); Navigation(this.navPathStack) { // 内部实现你的页面 }
子导航页需要使用NavDestination作为根节点。
NavDestination() { // 你的页面内容 } .hideTitleBar(true) .onWillAppear(() => { this.mPersonId = this.param['personId'] as string }) .onAppear(() => { this.init() }) .onShown(() => { }) .onDisAppear(() => { })
跳转与传参
router的跳转与入参方式如下
router.pushUrl({ url: 'pages/home/media/EmbyEpisodeDetail', // 目标url params: { "userId": this.userId, "itemId": item.Id } }, router.RouterMode.Single, (err) => { if (err) { console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`); return; } console.info('Invoke pushUrl succeeded.'); });
接收方式,在目的页面添加接收方法。
routerParams: Record<string, Object> = router.getParams() as Record<string, Object>; // 获取传递过来的参数对象 @State itemId: string = this.routerParams['itemId'] as string
Navigation如下
const params: Record<string, Object> = { "seriesId": item.Id, } this.navPathStack?.pushPathByName('EmbyEpisodeDetail', params)
接收方式
在Builder内定义好接收参数
@Builder export function EmbyEpisodeDetailBuilder(name: string, param: Object) { EmbyEpisodeDetail({ param: param as Record<string, Object> }) }
在Component里面进行处理
param: Record<string, Object> = {} // 在NavDestination生命周期的onWillAppear中进行传参的获取 this.itemId = this.param['itemId'] as string
下一篇 >>
网友留言(3 条)