鸿蒙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 条)