🎯 浅入主流路由解决方案推荐之 Navigation

⭐⭐⭐⭐⭐

📌 见解

1️⃣ Navigation组件是路由导航的根视图容器,NavDestination作为子页面的根容器,用于显示Navigation的内容区

2️⃣ 路由方案:HMRouter(官方比较推荐)、ZRouter(比较推荐)、Navigation(推荐)、Router(不推荐)

3️⃣ HMRouterZRouter两者都是基于原生Navigation进行二次封装

⚠️ 使用场景

功能场景 Navigation router
跨模块跳转 支持(需先import页面) 原生支持
跳转传参 ✅ 引用传递(性能更优) ✅ 深拷贝传递
获取指定页面参数 ✅ 支持 ❌ 不支持
返回指定路由 ✅ popToName/popToIndex ❌ 不支持
清理指定路由 ✅ removeByName/removeByIndexes ❌ 不支持
路由栈操作 ✅ 支持(如moveToTop) ❌ 不支持
共享元素动画 ✅ 支持 ❌ 不支持
设置页面属性 ✅ 背景模糊等(backgroundBlurStyle) ❌ 不支持
沉浸式页面 ✅ 原生支持 ❌ 需通过window配置
模态嵌套路由 ✅ 支持 ❌ 不支持
路由拦截 ✅ setInterception ❌ 不支持
路由数量限制 ✅ 无限制 ✅ 最多32个
一多能力支持 ✅ 支持 ❌ 不支持

🧩 拆解

🧱 routerMap:路由表配置项

// src/main/module.json5
"routerMap": "$profile:router_map",

🧱 route_map:路由表信息维护

// TODO: 需要自己在该文件夹下创建
// src/main/resources/base/profile/router_map.json
{
  "routerMap": [
    {
      "name": "Son",
      "pageSourceFile": "src/main/ets/components/Son.ets",
      "buildFunction": "SonBuilder",
      "data": {
        "description": "this is pageOne"
      }
    }
  ]
}

🧱 IndexPage:根容器

// Navigation根容器src/main/ets/pages/Index.ets
@Entry
@ComponentV2
struct Index {
  private navStack: NavPathStack = new NavPathStack()

  build() {
    Navigation(this.navStack) {
      Column() {
        Button('我要跳转了')
          .onClick(() => {
            // 页面传递的数据 & 目标页面传递的数据
            this.navStack.pushPathByName('Son', '我是汉堡黄🍔', (fromPageOneParma) => {
              console.info(`来自子页面的数据${fromPageOneParma.result as string}`)
            })
            this.navStack.setInterception({
              // 页面跳转前拦截
              willShow: (from, to, operation, animated) => {
              },
              // 页面跳转后回调
              didShow: (from, to, operation, animated) => {
              },
            })
          })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .hideTitleBar(true)
    .hideTitleBar(true) // 隐藏标题栏
  }
}

🧱 Son:子容器

// NavDestinationsrc/main/ets/components/Son.ets
@Builder
export function SonBuilder() {
  Son()
}

@ComponentV2
export struct Son {
  naviStack: NavPathStack | null = null
  naviInfo: NavPathInfo | null = null
  private paramFromHome: string | null = null

  build() {
    NavDestination() {
      Column({ space: 20 }) {
        Text(`传递过来的参数:${this.paramFromHome}`)
        Button('现在这里是子页面')
          .width('50%')
          .height(40)
          .onClick(() => {
            this.naviStack?.pop('来自汉堡的数据')
            this.naviStack?.setInterception({
              // 页面跳转前拦截
              willShow: () => {
                if (this.naviInfo?.name === 'PageOne') {
                  console.info('PageOne')
                }
              }
            })
          })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .hideTitleBar(true) // 隐藏标题栏
    .onReady((ctx: NavDestinationContext) => {
      this.naviStack = ctx?.pathStack
      this.naviInfo = ctx?.pathInfo
      if (ctx.pathInfo.param) {
        this.paramFromHome = ctx.pathInfo.param as string
      }
    })
  }
}

📝 官方以及其他开发者已经提供二次封装的路由方案,并且已经广泛使用,了解Navigation原声能力,能更快的切如第三方的路由方案

🌸🌼🌺

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐