「HarmonyNextOS」页面路由跳转Router更换为Navigation

前言

前段时间,鸿蒙发布了HarmonyNextOS系统,API直接升级到了12,许多API都发生了改变,页面跳转页从当初推荐的Router变换成Navigation,并且从API Version 10之后,都推荐使用NavPathStack来实现页面路由,也就是Navigation组件来实现页面跳转

这篇文章来看看两种路由跳转的前后变化,以及两种路由跳转的具体使用方法

1. Router和Navigation架构差异

从ArkUI组件树层级上来看,原先由Router管理的page在页面栈管理节点stage的下面。Navigation作为导航容器组件,可以挂载在单个page节点下,也可以叠加、嵌套。Navigation管理了标题栏、内容区和工具栏,内容区用于显示用户自定义页面的内容,并支持页面的路由能力。Navigation的这种设计上有如下优势:

  1. 接口上显式区分标题栏、内容区和工具栏,实现更加灵活的管理和UX动效能力;
  2. 显式提供路由容器概念,由开发者决定路由容器的位置,支持在全模态、半模态、弹窗中显示;
  3. 整合UX设计和一多能力,默认提供统一的标题显示、页面切换和单双栏适配能力;
  4. 基于通用UIBuilder能力,由开发者决定页面别名和页面UI对应关系,提供更加灵活的页面配置能力;
  5. 基于组件属性动效和共享元素动效能力,将页面切换动效转换为组件属性动效实现,提供更加丰富和灵活的切换动效;
  6. 开放了页面栈对象,开发者可以继承,能更好的管理页面显示。
    在这里插入图片描述

2. 具体使用方法

2.1 Router

这里的Router指的就是系统的@ohos.router,官方开发文档链接:页面路由(@ohos.router)

在之前使用router进行路由跳转非常方便,只需要在摁钮的点击事件触发router.pushUrl()方法即可完成跳转,参数用params进行传递(注:这里使用了PageConstant,作为所有页面跳转地址的集合,方便统一管理

// 父页面
import router from '@ohos.router';
import { UserInfoBean } from '../../bean/UserInfoBean';
import { PageConstant } from '../PageConstant';

@Entry
@Component
export struct UserCenterPage {
  @State userInfo: UserInfoBean = new UserInfoBean()
  
    build() {
      Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Start}) {
        List() {
          ListItem() {
            HeaderView({userInfo: this.userInfo})
              .onClick(() => {
                router.pushUrl({url: PageConstant.Url_User_Info_Page, params: {'userInfo': this.userInfo}})
              })
          }
        }
      }
      .padding({left: 16, right: 16})
      .backgroundColor($r('app.color.smart_F7F7F7'))
    }
}
// 子页面
import router from '@ohos.router'
import { UserInfoBean } from '../../bean/UserInfoBean'


struct UserInfoPage {
  @State userInfo: UserInfoBean = new UserInfoBean()
  
    aboutToAppear() {
      this.userInfo = router.getParams()?.['userInfo']
    }

    build() {
        //页面布局
    }

}
// 页面集合
export class PageConstant {

// 个人信息页面
static readonly Url_User_Info_Page = 'pages/UserCenter/UserInfoPage'
    
}

这就是使用router的页面跳转,相对比较简单且轻松

2.2 Navigation

在后续重构的项目中页面路由跳转使用了Navigation,并且也使用了静态库组件化的开发模式,所以会有一些功能模块组件需要额外执行的操作,如果只是单项目均在项目的对应文件中进行相应操作即可

1.在根控制器中创建NavPathStack并使用Navigation

注:这里是为了方便后面的页面可以进行在同一个NavPathStack路由栈中进行跳转操作

@Entry
@Component
struct Index {
    // 这里创建数据双向同步的父组件
    @Provide('pageStack') pageStack: NavPathStack = new NavPathStack()
    
    build() {
      Navigation(this.pageStack) {
          // 其他UI代码
        }
    }
}

2.在功能组件中创建route_map.json文件
需要在base文件夹下创建profile文件夹,并且在profile文件夹下创建route_map.json文件
,具体文件路径如图
在这里插入图片描述

3.在route_map.json文件中创建routerMap
具体routerMap模版如下,注buildFunction需要与子控制器中的入口函数保持一致
在这里插入图片描述

{
  // UserCenter组件中的routerMap
  "routerMap": [
    {
      "name": "UserInfoPage",
      "pageSourceFile": "src/main/ets/Pages/UserInfoPage.ets",
      "buildFunction": "UserInfoPageBuilder",
      "data": {
        "description" : "this is UserInfoPage"
      }
    },
    {
        //其他页面
    }
  ]
}

4.在功能组件的module.json5文件中添加routerMap

{
  "module": {
    "name": "userCenter",
    "type": "har",
    "deviceTypes": [
      "default",
      "tablet",
      "2in1"
    ],
    // 新增routerMap
    "routerMap": "$profile:route_map"
  }
}

5.UserCenter功能组件中的父控制器

注:这里同样采用PageConstant进行页面统一管理

import { UserInfoBean } from '../Beans/UserInfoBean'
import { PageConstant } from '../PageConstant'

@Entry
@Component
export struct UserCenterPage {
  @State userInfo: UserInfoBean = new UserInfoBean()
  @Consume pageStack: NavPathStack
   
    build() {
      Flex({direction: FlexDirection.Column, alignItems: ItemAlign.Start}) {
        List() {
          ListItem() {
            HeaderView({userInfo: this.userInfo})
              .onClick(() => {
                // Navgation With PageUrl
                this.pageStack.pushPathByName(PageConstant.Url_User_Info_Page, null, true)
              })
          }

        }
        .scrollBar(BarState.Off)
      }
      .padding({ left:16, right:16 })
      .backgroundColor($r('app.color.smart_F7F7F7'))
    }

}

6.UserCenter中的子控制器

注:子控制器需要使用NavDestination()进行承接,并且需要设置入口函数

@Builder
export function UserInfoPageBuilder() {
  UserInfoPage()
}

@Entry
@Component
export struct UserInfoPage {
  @Consume pageStack: NavPathStack

  build() {
    NavDestination() {
      Column() {
        Row() {

        }
      }
      .width('100%')
      .height('100%')
      .backgroundColor(Color.Pink)
    }
    .hideTitleBar(true)
  }
}

7.PageConstant文件
用于页面统一添加和管理

export class PageConstant {
  // 用户信息页面
  static readonly Url_User_Info_Page = 'UserInfoPage'

}

所以Navigation相比于router步骤会相对繁琐一些,但后续推荐更改为Navigation进行路由跳转。

3. 参考文档:

组件导航 (Navigation) (推荐)

页面路由 (@ohos.router)

总结

当前HarmonyOs仍在初步学习过程中,大家如果感兴趣或者有问题可以一起沟通交流 如果该文章对你有所帮助的话,可以点赞、收藏并关注一下!后续会持续更新更多技术内容

### ArkTSNavigationRouter 的用法与区别 在 ArkTS 开发环境中,`navigation` 和 `router` 是两个核心概念,用于管理应用内的页面跳转和状态传递。以下是它们的具体用法以及主要的区别。 #### 1. **Router 的基本功能** 路由器 (`router`) 主要负责定义和处理 URL 路径的变化,并将其映射到相应的组件或视图上。通过配置路由表,开发者可以轻松实现单页应用程序 (SPA) 的导航逻辑[^1]。 - 使用方式通常涉及声明式的路径匹配规则。 - 动态参数可以通过 `params` 或者查询字符串的形式获取并绑定至组件的状态中。 ```typescript // 定义路由表 const routes = [ { path: '/home', component: HomeComponent }, { path: '/profile/:id', component: ProfileComponent } ]; // 导航到特定路径 this.router.navigate(['/profile/123']); ``` #### 2. **Navigation 的高级特性** 相比之下,`navigation` 更加注重用户体验层面的操作,比如拦截器、过渡动画等附加功能[^3]。它不仅能够完成基础的页面切换任务,还可以支持更复杂的场景需求: - 添加全局性的守卫机制来验证权限; - 自定义加载指示符显示行为; - 实现引导流程(Onboarding)、教程提示等功能。 例如,在 Next.js 新版本推荐采用 `next/navigation` API 替代传统的 `next/router` 来获得更好的性能表现及额外增强选项[^2]。 #### 3. **关于 Refresh Token 处理** 当涉及到身份认证时,确保会话持续有效是一个重要话题。为了防止频繁重新登录带来的不便体验,可以借助 Axios 插件配合后端接口设计一套完善的自动续期策略[^4]。 具体做法如下所示: - 当检测到访问令牌过期错误响应码时触发刷新过程; - 成功取得新的凭证后再重试原始请求;失败则强制登出当前用户账户。 ```javascript import axios from 'axios'; axios.interceptors.response.use( response => { return response; }, error => { const originalRequest = error.config; if(error.response.status === 401 && !originalRequest._retry){ originalRequest._retry = true; // 防止无限循环 return new Promise((resolve, reject)=>{ axios.post('/refresh_token') .then(res=>{ localStorage.setItem('token', res.data.token); originalRequest.headers['Authorization'] = 'Bearer '+res.data.token; resolve(axios(originalRequest)); }) .catch(err=>reject(err)) }); } return Promise.reject(error); } ); ``` --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡酒交魂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值