鸿蒙Next开发日记 Day11 - 如何把项目中的router修改为Navigation

Ye-Mian-Tiao-Zhuan-Xing-Shi-Yan-Jiu.svg

早期入坑鸿蒙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 条)

  1. 电影大全
    电影大全 回复Ta
    《朱迪与潘趣(原声版)》喜剧片无广告高清版:https://www.jinzhuqq.com/dyvideo/37490.html
  1. 星空影院
    星空影院 回复Ta
    《我爸是神豪》短片剧高清在线免费观看:https://www.jgz518.com/xingkong/14447.html
  1. 江南影视
    江南影视 回复Ta
    《朱迪与潘趣(原声版)》喜剧片无广告高清版:https://www.jinzhuqq.com/dyvideo/37490.html

发表评论

验证码