HarmonyOS鸿蒙Next中关于使用HMRouter,向嵌套路由中的页面传参的问题

HarmonyOS鸿蒙Next中关于使用HMRouter,向嵌套路由中的页面传参的问题 目前使用HMRouter来管理路由,遇到这样一个问题,如下图所示:

cke_1036.png

页面1有个参数,跳转页面2时,将参数传递给页面2,页面2能在aboutToAppear中获取该参数,页面2是个容器,里面是一个HMNavaigation,将页面2-1设置为默认页面。

我目前遇到的问题是,如何将参数从页面1传递给页面2-1,请高手赐教,不胜感激!


更多关于HarmonyOS鸿蒙Next中关于使用HMRouter,向嵌套路由中的页面传参的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

你好,可以通过 pageUrl 传递参数,通过 HMRouterMgr.getCurrentParam 传入 HMParamType.all 获取URL的参数内容。

// Page2
import { HMRouterMgr, HMRouter, HMNavigation } from '@hadss/hmrouter';

@HMRouter({ pageUrl: "Page2" })
@Component
export struct Page2 {
  build() {
    Column() {
      // HMNavigation 容器
      HMNavigation({
        navigationId: 'Navigation2',
        homePageUrl: 'Page21?data=' + JSON.stringify(HMRouterMgr.getCurrentParam())
      })
    }
  }
}
// Page21 获取 url 上的参数 urlParam
import { HMPageParam, HMParamType, HMRouter, HMRouterMgr } from "@hadss/hmrouter";

@HMRouter({ pageUrl: "Page21" })
@Component
export struct Page21 {
  // 接收父组件 Page2 传递的参数
  @Prop param: Record<string, Object> = {};

  aboutToAppear() {
    // 获取 Page1 传过来的参数
    const param: HMPageParam = HMRouterMgr.getCurrentParam(HMParamType.all) as HMPageParam
    const data = param.urlParam?.get('data') as string
    this.param = JSON.parse(data)
    console.log("Page1 收到参数:", data);
  }

  build() {
    Column() {
      
    }
  }
}

完整示例代码:

import { HMPageParam, HMParamType, HMRouter, HMRouterMgr, HMNavigation } from "@hadss/hmrouter";

@Entry
@Component
struct Index {
  build() {
    Column() {
      HMNavigation({
        navigationId: 'MainNavigation', homePageUrl: 'Page1'
      })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

@HMRouter({ pageUrl: 'Page1' })
@Component
export struct Page1 {
  build() {
    Column() {
      Text("我是 Page1,点击跳转到 Page2")
        .fontSize(22)
        .margin(20)
        .onClick(() => {
          HMRouterMgr.push({
            pageUrl: "Page2",
            param: {
              id: 10086,
              title: "鸿蒙路由传参测试",
              content: "这是从 Page1 传过来的内容"
            }
          })
        })
    }
  }
}

@HMRouter({ pageUrl: "Page2" })
@Component
export struct Page2 {
  build() {
    Column() {
      HMNavigation({
        navigationId: 'Navigation2',
        homePageUrl: 'Page21?data=' + JSON.stringify(HMRouterMgr.getCurrentParam())
      })
    }
  }
}

@HMRouter({ pageUrl: "Page21" })
@Component
export struct Page21 {
  @Prop param: Record<string, Object> = {};

  aboutToAppear() {
    // 获取 Page1 传过来的参数
    const param: HMPageParam = HMRouterMgr.getCurrentParam(HMParamType.all) as HMPageParam
    const data = param.urlParam?.get('data') as string
    this.param = JSON.parse(data)
    console.log("Page1 收到参数:", data);
  }

  build() {
    Column() {
      Text("我是 Page2-1 子页面")
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 15 })

      // 直接展示传过来的参数
      Text(`ID:${this.param.id}`)
        .fontSize(20)
        .margin(5)
      Text(`标题:${this.param.title}`)
        .fontSize(20)
        .margin(5)
      Text(`内容:${this.param.content}`)
        .fontSize(20)
        .margin(5)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

更多关于HarmonyOS鸿蒙Next中关于使用HMRouter,向嵌套路由中的页面传参的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


相当优雅,高手!

上面大佬牛批,正好我也遇到了

既然page2已经获得了参数,
通过 AppStorage.setOrCreate 方法去配置参数

struct Index {
    modifier: MyNavModifier = new MyNavModifier();
    @State test01: string = ""

    aboutToAppear(): void {
        this.test01 = "123123123"
        AppStorage.setOrCreate<string>("test01",this.test01)
    }

    build() {
        Column() {
            // [Start hum_navigation]
            HMNavigation({
                navigationId: 'mainNavigationId',
                homePageUrl: 'MainPage',
                options: {
                    standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR,
                    modifier: this.modifier,
                }
            });
            // [End hum_navigation]
        }
        .height('100%')
        .width('100%')
        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]);
    }
}

在page2-1组件页面 添加即可

@StorageLink('test01') test01: string = ""

这个场景本质上是:

Page1 → Page2(容器页)

然后 Page2 内部的 HMNavigation 再自动打开默认页 Page2-1。

所以参数其实只传到了 Page2,并不会自动继续传给 Page2-1。

需要你在 Page2 中手动“二次透传”。

一般有两种方案:


方案1:Page2 中再次 push 参数(推荐)

最常见、最稳定。

Page1:

router.pushUrl({
  url: 'pages/Page2',
  params: {
    userId: '123'
  }
})

Page2:

@Entry
@Component
struct Page2 {

  private navPathStack: NavPathStack = new NavPathStack()

  aboutToAppear() {
    const params = router.getParams() as Record<string, Object>
    let userId = params['userId']

    // 手动传递给 Page2-1
    this.navPathStack.pushPath({
      name: 'Page2-1',
      param: {
        userId: userId
      }
    })
  }

  build() {
    Navigation(this.navPathStack) {

    }
  }
}

Page2-1:

aboutToAppear() {
  const param = this.getUIContext()
    .getRouter()
    .getParams()

  console.info(JSON.stringify(param))
}

核心思想:

Page2 收到参数后,

自己再 push 给 Page2-1。

这是 HMRouter / Navigation 最标准的做法。


方案2:使用全局状态共享(不推荐主路由参数这样干)

比如:

  • AppStorage
  • LocalStorage
  • Preference
  • 全局单例 Store

Page1:

AppStorage.setOrCreate('userId', '123')

Page2-1:

let userId = AppStorage.get('userId')

这种适合:

  • 用户信息
  • 登录态
  • 全局配置

不适合页面跳转参数。

否则后期页面关系会非常混乱。


你这里最关键的问题

你现在的:

HMNavigation 默认页

其实只是 Navigation 的“初始页面”。

它不会自动继承父页面参数。

也就是说:

Page1 -> Page2(params)

Page2-1 自动拿到 params

必须手动转发。


推荐最终结构

建议不要依赖“默认页”。

而是:

Page2 根据参数决定 push 哪个子页面。

例如:

aboutToAppear() {
  const params = router.getParams()

  this.navPathStack.pushPath({
    name: 'Page2-1',
    param: params
  })
}

这样以后:

  • Page2-1
  • Page2-2
  • Page2-3

都能灵活切换。

后期扩展性会好很多。


一句话总结

HMRouter 的参数只会传到当前目标页。

嵌套 Navigation 内部的默认页面不会自动继承参数,需要在 Page2 中手动再次 push 并透传 param 给 Page2-1。

不确定用哪个状态管理时,用AppStorage。

  1. 页面1或页面2在aboutToAppear中获取该参数时设置:
AppStorage.setOrCreate('xxxx', '页面1的值');
  1. 页面2-1里
@State pc:string | undefined = '默认';

  aboutToAppear(): void {
    this.pc = AppStorage.get<string>('xxxx');
  }

PS: @Provide和@Consume 也可以。

在 HarmonyOS 鸿蒙 Next 中,使用 HMRouter 向嵌套路由传参,可在调用路由跳转时通过 params 字段传入对象。例如:router.pushUrl({ url: 'targetPage', params: { key: 'value' } })。目标页面通过 router.getParams()@Entry 组件的 aboutToAppear 生命周期中读取 params 参数。嵌套路由若为子页面,同样使用 getParams() 获取父级传递的数据。

在HMRouter中,页面1到页面2的参数可直接在页面2的aboutToAppear获取。若需传递给嵌套的页面2-1,可在页面2中持有NavPathStack,并在获取参数后通过代码跳转并传参。示例:

// 页面2
@State navPathStack: NavPathStack = new NavPathStack()

aboutToAppear() {
  const param = HMRouterMgr.getCurrentParam() // 获取页面1传来的参数
  // 等待Navigation就绪后,推送子页面并传参
  setTimeout(() => {
    this.navPathStack.pushPathByName('page2_1', param)
  }, 0)
}

build() {
  Navigation(this.navPathStack) {
    // 可留空或将默认内容设为占位,实际显示将立即被push的page2_1替换
  }
  .navDestination(this.navPathStack)
}

这样页面2-1的aboutToAppear即可通过HMRouterMgr.getCurrentParam()接收参数。若页面2-1已是默认视图且不愿用动态推送,也可改用@Provide/@Consume在页面2接收参数后同步给子组件。

回到顶部