HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来

HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来 在这篇文章中,将逐步的介绍,如何通过Navigation进行页面间的切换。

1、页面跳转的准备工作

首先,开发者需要创建一个NavPathStack对象并作为构造入参传给Navigation组件,以实现二者的绑定,后续的路由操作均基于该NavPathStack展开。

// BasicNavigation.ets

@Component
struct BasicNavigation {
  stack: NavPathStack = new NavPathStack()

  build() {
    // 将导航控制器NavPathStack 绑定至Navigation中。
    Navigation(this.stack) {
        // Navigation作为路由根容器,可以不显示任何内容
    }
  }
}

此时我们已经构建好了一个Navigation根容器并绑定了导航控制器NavPathStack,接下来我们需要构建显示的页面。

Step1、构建子页面

为每个NavDestination声明对外的实例化方法,如代码中的PageOneBuilder,执行该方法会创建一个BasicNavDestination的自定义组件,该组件就是一个Navigation的子页面。

// BasicNavDest.ets

// 组件实例化方法,该方法会创建BasicNavDestination自定义组件作为Navigation的页面
@Builder
export function PageOneBuilder() {
  BasicNavDestination({
    name: 'pageOne'
  });
}

// NavDestination组件
@Component
struct BasicNavDestination {
  name: string = 'NA'

  build() {
    NavDestination() {
        // 页面中的内容
    }
  }
}

Step2、配置Navigation路由表

将步骤一中写好的实例化方法与它的name(开发者自定义)写在路由表的配置文件中(entry/src/main/resources/base/profile/route_map.json开发者自行创建)。

// entry/src/main/resources/base/profile/route_map.json
{
  "routerMap": [
    {
      "name": "basicPageOne", // 路由页面的唯一标识符
      "pageSourceFile": "src/main/ets/pages/BasicFeature/BasicNavDest.ets", // 源码所在地址
      "buildFunction": "PageOneBuilder", // 页面的实例化方法名称
    },
  ]
}

Step3、使能Navigation路由表

将步骤二中创建的route_map.json配置为系统路由表。开发者需要在当前模块的module.json5中,为“module”的内容新增一个配置项,例如:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone"
    ],
    "pages": "$profile:main_pages",
    "routerMap": "$profile:route_map", // 新增这一行,使能路由表
    "abilities": [...]
  }
}

2、NavPathStack的获取

Navigation根容器和子页面以及路由表配置完成后,即可通过调用NavPathStack的api来实现页面之间的跳转。以下通过按钮点击来触发路由操作:

Button('跳转到basicPageOne')
  .width(330)
  .margin(7)
  .onClick(() => {
    this.stack.pushPath({name: 'basicPageOne'})
  })

对于没有分栏诉求的应用,推荐将Navigation的导航栏NavBar隐藏,基于NavDestination组件进行所有页面功能的开发,例如:

// BasicNavigation.ets

@Component
struct BasicNavigation {
  stack: NavPathStack = new NavPathStack()

  aboutToAppear(): void {
    // 2.将basicPageOne作为Navigation的首页显示
    this.stack.pushPath({name: 'basicPageOne'})
  }

  build() {
    Navigation(this.stack) {
        // Navigation作为路由根容器,可以不显示任何内容
    }
    // 1. 将Navigation导航栏NavBar进行隐藏
    .hideNavBar(true)
  }
}

这样一来,所有的操作均会基于NavDestination组件展开,开发者可以将导航控制器对象NavPathStack存在全局的AppStorage中,方便后续在其他NavDestination中的路由控制:

// BasicNavigation.ets

@Component
struct BasicNavigation {
  stack: NavPathStack = new NavPathStack()

  aboutToAppear(): void {
    // 1.将当前导航控制器对象存储至AppStorage中,可以在同应用内的任意地方获取
    AppStorage.setOrCreate<NavPathStack>('basicNavigationStack', this.stack)
    this.stack.pushPath({name: 'basicPageOne'})
  }

  build() {
    Navigation(this.stack) {
       // Navigation作为路由根容器,可以不显示任何内容
    }
    .hideNavBar(true)
  }
}

此外,还有其他的获取NavPathStack的方式,参见系列后续章节。

3、路由操作方法

navigation框架有三种主要的路由操作:push、pop、replace,下文会分别介绍。

3.1 Push

push操作用以创建一个新的页面视图。主要分为两种,带有异步返回结果的pushDestination和不带返回结果的pushPath。

如果push过程发生了错误,pushPath会跳转到一个空白的页面,pushDestination则会将该错误携带错误码返回给开发者。相应的,如果跳转成功,pushDestination会将成功的结果返回给开发者。示例如下:

// BasicNavDest.ets

Button('pushDestination跳转basicPageOne')
  .width(330)
  .margin(7)
  .onClick(() => {
    // pushDestination会带有异步结果返回
    this.stack.pushDestination({name: 'basicPageOne'})
      .then(() => {
        // .then分支表明本次跳转成功,没有发生错误
        console.log('AceNavigation', 'pushDestination跳转basicPageOne', 'success!')
      })
      .catch((err: Object) => {
        // .catch分支表明本次跳转失败,错误信息包含在入参err中
        console.log('AceNavigation', 'pushDestination跳转basicPageOne', 'failed!')
        console.log('AceNavigation', '-- err info: ' + JSON.stringify(err))
      })
  })
Button('pushPath跳转basicPageOne')
  .width(330)
  .margin(7)
  .onClick(() => {
    // pushPath不带有返回结果
    this.stack.pushPath({name: 'basicPageOne'})
  })

除了是否返回结果外,pushPath与pushDestination在用法上没有区别。开发者还可以通过传入NavigationOptions参数来控制本次push的行为,例如,实现一个单实例跳转、无动画跳转:

// BasicNavDest.ets

Button('单实例、无动画跳转basicPageOne')
  .width(330)
  .margin(7)
  .onClick(() => {
    // 指定launchMode为MOVE_TO_TOP_SINGLETON,会复用Index最大的同名页面;指定animated为false则会禁用本次跳转的动画。
    this.stack.pushPath({name: 'basicPageOne'}, {launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON, animated: false})
  })

3.2 Pop

pop操作用以删除Navigation导航栈顶页面,可以传入参数来控制是否禁用动画。例如:

// BasicNavDest.ets

Button('Pop有动画pop')
  .width(330)
  .margin(7)
  .onClick(() => {
    // 接口无参数传递时默认有动画
    this.stack.pop()
  })
Button('Pop无动画pop')
  .width(330)
  .margin(7)
  .onClick(() => {
    // 传递animated参数为false时,本次操作会禁用动画
    this.stack.pop(false)
  })

3.3 Replace

replace操作会用一个新的页面替换当前NavPathStack栈顶页面,如下示例:

// BasicNavDest.ets

Button('replace跳转basicPageOne')
  .width(330)
  .margin(7)
  .onClick(() => {
    // 使用basicPageOne替换当前栈顶页面
    this.stack.replacePath({name: 'basicPageOne'})
  })
Button('replace跳转basicPageTwo')
  .width(330)
  .margin(7)
  .onClick(() => {
    // 使用basicPageTwo替换当前栈顶页面。basicPageTwo上文示例中没有创建,请参照basicPageOne自行实现。
    this.stack.replacePath({name: 'basicPageTwo'})
  })

2.1.3章节的动画示例分别如下(push&&pop、replace):

(未完待续……)


更多关于HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS Next的ArkUI中,Navigation组件实现基础路由跳转需使用Router模块。关键步骤如下:

  1. 配置路由路径: 在entry/src/main/resources/base/profile/main_pages.json定义路由页面路径,如:
{
  "src": [
    "pages/Index",
    "pages/Detail"
  ]
}
  1. 页面跳转方法:
  • 使用router.pushUrl()进行页面推入:
router.pushUrl({
  url: 'pages/Detail'
})
  • 使用router.back()返回上一页
  1. 参数传递: 通过params对象传递参数:
router.pushUrl({
  url: 'pages/Detail',
  params: { id: 123 }
})

接收方使用router.getParams()获取参数。

更多关于HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,Navigation组件配合NavPathStack提供了强大的路由管理能力。您已经详细介绍了基础配置和三种核心路由操作:

  1. 基础配置要点:

    • 必须创建NavPathStack并与Navigation绑定
    • 通过@Builder构建子页面组件
    • 路由表配置在route_map.json中
    • 需要在module.json5中启用路由表
  2. 路由操作对比:

    • Push操作:
      • pushPath:简单跳转,无返回结果
      • pushDestination:支持Promise,可捕获错误
      • 支持NavigationOptions参数控制跳转行为
  3. 实际开发建议:

    • 对于无分栏需求的应用,建议隐藏NavBar(hideNavBar(true))
    • 将NavPathStack存入AppStorage便于全局访问
    • 合理使用launchMode控制页面实例化方式

您提供的代码示例已经非常完整,特别是关于路由表配置和三种路由操作的实现。需要注意的是,replace操作会销毁当前页面实例,适合登录页跳转主页等场景。

动画控制方面,通过animated参数可以灵活控制转场效果,这对提升用户体验很重要。

后续可以继续探讨:

  • 路由传参的实现方式
  • 复杂场景下的路由管理
  • 页面生命周期与路由的关系
  • 自定义转场动画等高级特性
回到顶部