HarmonyOS 鸿蒙Next中夸页面传参

HarmonyOS 鸿蒙Next中夸页面传参

A页面首页登陆后可以跳转到B页面设置,用户设置完成后B页面向A页面传参
B页面代码:

.onClick(() => {
    router.pushUrl(
        {
            url:'pages/Index',
            params:{
                a:this.a
            }
        }
    )
}

在A页面获取的时候@State params:object = router.getParams(),后面要用的时候用this.params[‘a’]

但是程序运行时会先到A页面,由于还未进入过B页面,所以获取不到router.getParams(),进而导致整个程序崩溃

请问这种情况该如何解决,谢谢!


更多关于HarmonyOS 鸿蒙Next中夸页面传参的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

【背景知识】

  1. JsCrash异常根据不同的异常场景,在Reason字段进行了分类,分为Error、TypeError、SyntaxError、ReferenceError、RangeError等错误类型。
  2. TypeError(类型错误):运行时最常见的异常,表示变量或参数不是预期类型。
  3. getParams:获取发起跳转的页面往当前页传入的参数。

【问题定位】

  1. 查看faultlogger下的故障日志,故障原因是TypeError类型错误,异常信息是Cannot load property of null or undefined,无法加载空值或未定义的属性。
    Reason:TypeError
    Error name:TypeError
    Error message:Cannot load property of null or undefined
    Stacktrace:
        at TestLoadSecondPage (entry/src/main/ets/pages/TestLoadSecondPage.ets:6:29)
        at anonymous (entry/src/main/ets/pages/TestLoadSecondPage.ets:66:26)
        at pushUrl (../../../foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/jsUIContext.js:1010:1)
        at anonymous (entry/src/main/ets/pages/TestLoadPage.ets:18:11)
    
  2. 从故障堆栈中可以看到应用在执行pushUrl跳转到新的页面时出现了空值或未定义的属性。
  3. 排查应用是否使用router.getParams()获取上一个页面传递过来的参数,但实际页面跳转时传递的参数为空。
    @Entry
    @Component
    struct TestLoadSecondPage {
      router : 
      @State message : string = (this.getUIContext().getRouter().getParams() as Record<string, string>)['a'];
    
      build() {
        RelativeContainer() {
          Text(this.message)
            .id('LoadUndefinedSecondPageHelloWorld')
            .fontSize($r('app.float.page_text_font_size'))
            .fontWeight(FontWeight.Bold)
            .alignRules({
              center: { anchor: '__container__', align: VerticalAlign.Center },
              middle: { anchor: '__container__', align: HorizontalAlign.Center }
            })
        }
        .height('100%')
        .width('100%')
      }
    }
    

【修改建议】

在使用getParams获取传递的参数时需要校验是否为空。

@Entry
@Component
struct TestLoadSecondPage {
  @State message : string = this.getUIContext().getRouter().getParams()
    ? (this.getUIContext().getRouter().getParams() as Record<string, string>)['a'] : 'emptyMsg';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('TestLoadSecondPageHelloWorld')
        .fontSize($r('app.float.page_text_font_size'))
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next中夸页面传参的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


跳转传参

import { Navigation } from '@kit.ArkUI';
Navigation.pushPath({
  path: 'SecondPage',
  params: { id: 1 }, // 支持对象形式传参
});

设置参数默认值,通过生命周期函数onPageShow动态更新参数,避免初始化时未定义。

// A页面初始化时设置空对象

@State params: object = {}

onPageShow() {

  // 页面显示时更新参数

  this.params = router.getParams() || {}
}

完整方案

// A页面

import router from '@kit.ArkUI';

@Entry
@Component
struct IndexPage {

  @State params: object = {}

  onPageShow() {

    this.params = router.getParams() || {}
  }

  build() {

    Column() {

      Text(this.params?.['a']?.toString() || '未设置参数')
    }
  }
}

// B页面

Button('确认')
  .onClick(() => {
    router.pushUrl({
      url: 'pages/Index',
      params: { a: this.a }
    })
  })

在HarmonyOS Next中,跨页面传参主要通过以下方式实现:

  1. 使用router.pushUrl()params参数传递简单数据:
router.pushUrl({
  url: 'pages/SecondPage',
  params: {id: 123, name: 'test'}
})
  1. 通过AbilityContextstartAbility()传递复杂对象:
let want = {
  deviceId: '',
  bundleName: 'com.example.app',
  abilityName: 'SecondAbility',
  parameters: {
    userData: {id: 1, name: '张三'}
  }
}
this.context.startAbility(want)
  1. 使用AppStorageLocalStorage进行全局状态管理共享数据。

接收方在onPageShow()onCreate()中通过router.getParams()获取参数。

在HarmonyOS Next中处理跨页面传参时,建议采用以下方式避免空指针问题:

  1. 使用可选链操作符安全访问参数:
@State params: object = router.getParams() || {}; // 设置默认空对象
// 使用时
const value = this.params?.['a']; // 安全访问
  1. 或者使用类型守卫检查参数存在性:
if (this.params && 'a' in this.params) {
    // 安全使用this.params['a']
}
  1. 也可以考虑使用AppStorage进行全局状态管理,避免直接依赖路由参数:
// B页面存储
AppStorage.setOrCreate('a', this.a);

// A页面获取
@StorageLink('a') a: any;

这些方法都能有效避免因未传参导致的程序崩溃问题。

回到顶部