当前位置:首页>鸿蒙APP>鸿蒙ArkTS中Navigation与router的用法与区别(含完整示例代码)

鸿蒙ArkTS中Navigation与router的用法与区别(含完整示例代码)

  • 2026-11-10 02:53:23
鸿蒙ArkTS中Navigation与router的用法与区别(含完整示例代码)

在鸿蒙ArkTS开发中,Navigation和router是实现页面跳转、导航管理的核心工具,很多开发者容易混淆两者的用法——有人用Navigation做页面跳转,有人用router管理导航栏,其实两者定位完全不同,各司其职。

核心结论先明确:Navigation是UI组件,用于构建页面导航栏、管理页面栈,侧重“页面UI展示与本地页面切换”;router是路由模块,用于跨页面(甚至跨模块)跳转、传递参数,侧重“页面间的逻辑跳转与通信”。

本文将从「单独用法」「核心区别」「结合使用场景」三个维度,搭配ArkTS V2(HarmonyOS NEXT)可直接运行的示例代码,帮你彻底分清两者,避免踩坑,看完就能落地实战。

一、先搞懂:Navigation的用法(UI组件,管页面导航与本地切换)

1. 核心定位

Navigation是鸿蒙ArkUI提供的导航组件,本质是一个UI容器,核心作用有两个:① 自动生成导航栏(标题、返回按钮、右侧操作按钮);② 管理本地页面栈(通过push、pop实现当前页面内的子页面切换),无需依赖router模块。

适用场景:单页面内的子页面切换(如列表页→详情页,且详情页仅在当前页面内复用)、快速构建带导航栏的页面,无需手动写导航栏布局。

2. 完整示例代码(可运行)

// ArkTS V2 Navigation示例:本地页面栈切换(无需router)@ComponentV2@Entrystruct NavigationDemo {  // 用于管理Navigation的页面栈  private navController: NavController = new NavController();  build() {    // 根容器:Navigation,配置导航栏    Navigation(this.navController) {      // 首页内容(Navigation的默认页面)      Column({ space: 20 }) {        Text("Navigation首页")          .fontSize(22)          .fontWeight(600);        // 跳转至子页面(本地页面栈push)        Button("跳转到子页面")          .width("80%")          .onClick(() => {            // push:添加子页面到页面栈,显示导航栏返回按钮            this.navController.pushUrl({              url: "pages/NavigationSubPage" // 子页面路径(需在pages.json配置)            });          });      }      .padding(20)    }    // 导航栏配置    .title("Navigation导航示例") // 导航栏标题    .titleMode(NavigationTitleMode.FREE) // 标题模式(自由模式)    .toolbarItems([      // 导航栏右侧操作按钮      {        icon: $r("app.media.ic_settings"), // 自定义图标(可替换)        action: () => {          console.log("点击了导航栏右侧设置按钮");        }      }    ])    .width("100%")    .height("100%");  }}// 子页面:NavigationSubPage.ets(需在pages.json中注册)@ComponentV2struct NavigationSubPage {  build() {    Column({ space: 20 }) {      Text("Navigation子页面")        .fontSize(20)        .fontWeight(500);      // 返回上一页(本地页面栈pop)      Button("返回首页")        .width("80%")        .onClick(() => {          // pop:从页面栈中移除当前子页面,返回上一页          navController.pop();        });    }    .padding(20)  }}

3. Navigation核心要点

  • 依赖NavController:通过NavController管理页面栈,实现push(跳转)、pop(返回)、popToRoot(返回根页面)等操作;

  • 导航栏可自定义:支持设置标题、返回按钮、右侧工具栏、导航栏样式(背景色、字体等);

  • 页面栈是“本地”的:跳转的子页面仅在当前Navigation容器内有效,无法跨Navigation组件跳转;

  • 无需配置路由:子页面仅需在pages.json中注册,无需额外配置路由规则。

二、再掌握:router的用法(路由模块,管跨页面跳转与通信)

1. 核心定位

router是鸿蒙提供的路由模块(导入@ohos.router),本质是一个逻辑跳转工具,核心作用有两个:① 实现跨页面、跨模块的页面跳转(不受Navigation容器限制);② 实现页面间的参数传递(简单参数、复杂对象均可);③ 管理全局页面栈。

适用场景:跨页面跳转(如首页→设置页、不同模块间的页面跳转)、页面间传递参数、全局页面栈管理(如清除所有页面、返回指定页面)。

2. 完整示例代码(可运行)

// ArkTS V2 router示例:跨页面跳转+参数传递import router from '@ohos.router'; // 导入router模块// 页面A:跳转发起页@ComponentV2@Entrystruct RouterPageA {  build() {    Column({ space: 20 }) {      Text("Router跳转页面A")        .fontSize(22)        .fontWeight(600);      // 1. 简单参数跳转(url拼接)      Button("跳转到页面B(简单参数)")        .width("80%")        .onClick(async () => {          await router.pushUrl({            url: "pages/RouterPageB?name=鸿蒙&age=25" // 拼接简单参数          });        });      // 2. 复杂参数跳转(params传递)      Button("跳转到页面B(复杂参数)")        .width("80%")        .onClick(async () => {          await router.pushUrl({            url: "pages/RouterPageB",            params: {              user: { name: "鸿蒙开发者", age: 25, skill: "ArkTS" } // 复杂对象参数            }          });        });    }    .padding(20)    .width("100%")    .height("100%");  }}// 页面B:跳转目标页(接收参数)@ComponentV2@Entrystruct RouterPageB {  // 页面加载时接收参数  async onCreate() {    const params = await router.getParams(); // 获取路由参数    console.log("接收的参数:", params);    // 简单参数:params = { name: "鸿蒙", age: "25" }    // 复杂参数:params = { user: { name: "鸿蒙开发者", ... } }  }  build() {    Column({ space: 20 }) {      Text("Router目标页面B")        .fontSize(20)        .fontWeight(500);      // 返回上一页      Button("返回页面A")        .width("80%")        .onClick(async () => {          await router.back(); // 返回上一页        });      // 清除所有页面,返回根页面(如首页)      Button("返回根页面")        .width("80%")        .backgroundColor("#f56c6c")        .fontColor("#fff")        .onClick(async () => {          await router.clear(); // 清除全局页面栈        });    }    .padding(20)  }}

3. router核心要点

  • 需导入模块:必须导入@ohos.router才能使用,核心API有pushUrl(跳转)、back(返回)、clear(清除页面栈)、getParams(获取参数);

  • 支持跨模块跳转:不受Navigation容器限制,可跳转至其他模块的页面;

  • 参数传递灵活:支持url拼接简单参数(字符串、数字),也支持params传递复杂对象(对象、数组);

  • 管理全局页面栈:所有通过router跳转的页面,都在全局页面栈中,可通过clear()清除所有页面。

三、关键区别:Navigation vs router(一张表分清)

很多开发者混淆两者,核心是没分清“UI组件”和“逻辑模块”的定位,以下是最核心的区别,结合使用场景,一目了然:

对比维度

Navigation

router

核心定位

UI组件,用于构建导航栏、管理本地页面栈

路由模块,用于跨页面/跨模块跳转、参数传递

核心作用

1. 生成导航栏(标题、返回键);2. 本地子页面切换(push/pop)

1. 跨页面/跨模块跳转;2. 页面间参数传递;3. 全局页面栈管理

页面栈范围

本地页面栈(仅在当前Navigation容器内)

全局页面栈(所有router跳转的页面)

跳转范围

仅能跳转当前Navigation内的子页面,无法跨模块

可跨页面、跨模块跳转,不受容器限制

参数传递

支持,但仅能传递简单参数,且仅限本地页面栈

支持简单参数、复杂对象,跨页面/跨模块均可传递

依赖项

依赖NavController管理页面栈

需导入@ohos.router模块,无需依赖UI组件

适用场景

单页面内子页面切换、快速构建带导航栏的页面

跨页面/跨模块跳转、页面间参数传递、全局页面管理

四、实战场景:Navigation与router结合使用(最常用)

实际开发中,两者并非对立,而是结合使用——用Navigation构建页面导航栏和本地页面切换,用router实现跨模块跳转,兼顾UI体验和逻辑跳转需求。

结合示例代码(可运行)

// 结合示例:Navigation管导航栏+本地切换,router管跨模块跳转import router from '@ohos.router';@ComponentV2@Entrystruct NavRouterCombineDemo {  private navController: NavController = new NavController();  build() {    // Navigation:构建导航栏,管理本地页面栈    Navigation(this.navController) {      Column({ space: 20 }) {        Text("首页(Navigation+router结合)")          .fontSize(22)          .fontWeight(600);        // 1. 本地跳转(Navigation)        Button("本地跳转:子页面")          .width("80%")          .onClick(() => {            this.navController.pushUrl({ url: "pages/LocalSubPage" });          });        // 2. 跨模块跳转(router)        Button("跨模块跳转:设置页")          .width("80%")          .backgroundColor("#409eff")          .fontColor("#fff")          .onClick(async () => {            await router.pushUrl({ url: "pages/SettingPage" });          });      }      .padding(20)    }    .title("首页导航")    .width("100%")    .height("100%");  }}// 本地子页面(Navigation管理)@ComponentV2struct LocalSubPage {  build() {    Column({ space: 20 }) {      Text("本地子页面(Navigation管理)")        .fontSize(20);      Button("返回首页")        .width("80%")        .onClick(() => navController.pop());    }    .padding(20);  }}// 跨模块页面(router跳转目标页)@ComponentV2@Entrystruct SettingPage {  build() {    Column({ space: 20 }) {      Text("设置页(跨模块,router跳转)")        .fontSize(20);      Button("返回首页")        .width("80%")        .onClick(async () => await router.back());    }    .padding(20);  }}

结合使用核心原则

  • 页面内的子页面切换(无需跨模块):用Navigation的push/pop,体验更流畅,无需额外配置路由;

  • 跨页面、跨模块跳转:用router的pushUrl,配合getParams传递参数,实现全局跳转;

  • 导航栏统一用Navigation:避免手动写导航栏布局,提升开发效率和UI一致性。

五、常见踩坑点(必看)

  • 坑1:用Navigation跨模块跳转——会报错,Navigation仅能管理本地页面栈,跨模块必须用router;

  • 坑2:用router构建导航栏——router是逻辑模块,无UI展示能力,导航栏必须用Navigation;

  • 坑3:Navigation跳转不注册页面——子页面必须在pages.json中注册,否则无法跳转;

  • 坑4:router传递复杂对象不序列化——虽然ArkTS V2支持直接传递对象,但建议用JSON.stringify/parse处理,避免参数丢失;

  • 坑5:混淆页面栈——Navigation的页面栈是本地的,router的页面栈是全局的,clear()仅清除router的全局页面栈,不影响Navigation的本地页面栈。

六、总结

一句话分清两者:Navigation管“UI导航和本地切换”,router管“逻辑跳转和跨模块通信”,两者结合是鸿蒙ArkTS开发中页面导航的最佳实践。

核心用法回顾:

  • 需要导航栏、本地子页面切换 → 用Navigation + NavController;

  • 需要跨页面、跨模块跳转、传递参数 → 用router模块;

  • 实际开发 → 两者结合,兼顾UI体验和逻辑跳转需求。

本文所有示例代码均可直接复制运行,建议动手实操一遍,快速掌握两者的用法和区别,避免开发中踩坑。后续开发中,根据跳转场景选择合适的工具,才能高效开发鸿蒙原生应用。

最新文章

随机文章