router参数传递和接收示例
===============

#### 问题现象

在使用router进行页面路由跳转时，数据从页面一传输到页面二后，有以下常见问题：

1.  无法获取参数。
2.  参数里封装了函数，却无法调用。

#### 背景知识

[router](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router)通过[pushUrl](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router#pushurl)、[replaceUrl](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router#replaceurl)、[pushNamedRoute](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router#pushnamedroute)、[replaceNamedRoute](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router#replacenamedroute)四种方式跳转并传递参数页面。

跳转方法的参数形式：

*   pushUrl与replaceUrl描述页面信息的参数为[RouterOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-router#routeroptions)，传递参数结构形式为：
    
    {
      url: 'page/onePage', _// 传递的方式，必填参数_
      params: Object, _// 传递的数据，必填参数_
      recoverable: true _// 页面是否可恢复，该参数为非必填参数，默认为true_
    }
    

*   pushNamedRoute与replaceNamedRoute描述页面信息的参数为[NamedRouterOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-router#namedrouteroptions10)，传递参数结构形式为：
    
    {
      name: 'Welcome', _// 传递的方式，必填参数_
      params: Object, _// 传递的数据，必填参数_
      recoverable: true _// 页面是否可恢复，该参数为非必填参数，默认为true_
    }
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f6/v3/Jza3-69WQ2GGYgRhnpXO2A/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T133954Z&HW-CC-Expire=86400&HW-CC-Sign=890DB20649F3EE915B56817A219D5E5F8CB9AAAAB5EB70B2806BEF44EAEECC4D)
    
    params不支持传递方法和系统返回的复杂对象。
    

获取参数的方式：[getParams](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-uicontext-router#getparams)。获取的参数数据结构和传递的参数一致。

#### 问题定位

对于跳转后调用方法失败的问题，需先确认params传递的数据类型是否合法，特别注意params参数不能传递方法和系统接口返回的复杂对象，仅能包含基础类型的数据；

若无法获取参数，可以按照以下步骤进行定位：

1.  首先确定页面跳转时params参数是否为空或有效；
2.  其次，确保正确获取params参数，接收params参数的变量类型与params类型必须一致。

#### 分析结论

*   当跳转传递的参数不为空时，考虑创建的params是否有效并检查params传递的类型情况。若params也没有问题，则考虑接收参数的问题；以pushUrl为例，参考以下形式：
    
    this.getUIContext().getRouter().pushUrl({
      url: 'pages/routerpage2',
      params: new routerParams('message', \[123, 456, 789\])
    })
    
*   router传递的参数会经过序列化，过程中会丢失方法。

#### 修改建议

完整参数传递代码如下：

*   页面一：
    
    _// 定义公共参数类_
    export class InfoTmp {
      age: number = 0;
    }
    
    export class ParamInfo {
      name: string = '';
      info: InfoTmp = new InfoTmp();
    }
    
    _// 通过this.getUIContext().getRouter().pushUrl跳转至目标页携带params参数_
    @Entry
    @Component
    struct Index {
      build() {
        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
          Text('这是第一页')
            .fontSize(50)
            .fontWeight(FontWeight.Bold);
          Button() {
            Text('next page')
              .fontSize(25)
              .fontWeight(FontWeight.Bold)
              .margin(10);
          }
          .type(ButtonType.Capsule)
          .margin({ top: 20 })
          .backgroundColor('#F1F3F5')
          .onClick(() => {
            const params = new ParamInfo();
            params.name = 'Welcome';
            params.info.age = 20;
            this.getUIContext().getRouter().pushUrl({
              url: 'pages/Second',
              params: params
            });
          });
        }
        .width('100%')
        .height('100%');
      }
    }
    

*   页面二：
    
    import { ParamInfo } from './Index';
    
    _// 在second页面中接收传递过来的参数_
    @Entry
    @Component
    struct Second {
      @State params: ParamInfo = this.getUIContext().getRouter().getParams() as ParamInfo;
    
      aboutToAppear(): void {
        _// 方案一_
        let params = (this.getUIContext().getRouter().getParams() as Record<string, object>);
        let name = params.name;
        let info = params.info;
        console.info(\`Succeeded in completing PlanOne. params:{name: ${name}, info: ${info}}. \`);
        _// 方案二_
        let paramInfo: ParamInfo = this.getUIContext().getRouter().getParams() as ParamInfo;
        console.info(\`Succeeded in completing PlanTwo. params:{name: ${paramInfo.name}, info.age: ${paramInfo.info.age}}. \`);
      }
    
      build() {
        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
          Text(\`第一页传来的数值:${this.params.name}\`)
            .fontSize(20)
            .margin({ top: 20 })
            .backgroundColor(Color.Transparent);
        }
        .width('100%')
        .height('100%');
      }
    }
    

页面二参数接收有以下两种方式，对比如下：

| 
方案

 | 

优点

 | 

缺点

 | 

应用场景

 |
| :-- | :-- | :-- | :-- |
| 

方案一：转成Record

 | 

无需定义数据类

 | 

遇到嵌套类型数据处理麻烦

 | 

适用于只有基本类型场景

 |
| 

方案二：转成特定的类

 | 

嵌套类型数据处理简单

 | 

需要事先定义好数据类

 | 

适用于嵌套数据类型场景

 |

#### 常见FAQ

Q：params是否支持抽象类的传递？

A：不支持，复杂的页面传参建议使用Navigation。

Q：params传递HashMap类型数据，目标页面无法获取到内容如何解决？

A：router传递的参数会经过序列化，过程中会丢失方法。所以无法使用map，list传参。推荐使用Navigation。

Q：router路由跳转时params传入callback类型无效？

A：callback为回调函数方法，router的params参数不支持传递方法，因此无效。可以尝试使用[EventHub](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-eventhub)实现类似的效果。

Q：params如何传递属性字符串、ArrayBuffer、PixelMap类型的数据？

A：router不支持传递函数和嵌套复杂结构类型的数据，可使用[AppStorage](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-appstorage)或[EventHub](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-inner-application-eventhub)实现类似的效果。推荐使用Navigation。

Q：router获取的参数为什么无法清空？

A：router.getParams()获取的是路由记录中的只读参数副本，参数与页面实例绑定。每次onPageShow显示时都会读取同一份参数。需主动修改参数对象，每次跳转时强制传递新对象，参考代码如下：

this.getUIContext().getRouter().pushUrl({
  url: 'pages/Page',
  params: {} _// 若不传递参数，传空对象，覆盖旧对象。_
});

Q：如何使用router.back()返回上一个界面并传参？

A：[RouterOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-router#routeroptions)中url设置为空字符，params传入传递的参数数据。