鸿蒙 navigation路由跳转,页面struct 下的生命周期、onShow、onHidden等不会触发问题

经常用安卓思维考虑问题,用习惯了Router方式跳转,但是官方推荐用 navigation,当然它有它的有点, 也有小瑕疵,用了api11 后 发现 navigation路由跳转 ,只要被它包裹的跳转到下页面的,有些生命周期是拿不到的,比如onShow,onHidden等 ,估计小伙伴们也遇到了。庆幸的是api12 更新了,上面可以了哈,下面是以前的和现在的实例代码,对比就知道了哈

以前:

复制代码
 @Builder
  pageMap(name: string, param: object) {
    NavDestination() {
      // 根据模块名,获取WrappedBuilder对象,通过builder接口创建页面
      DfRouter.getBuilder(name).builder(param);
    }
    .hideTitleBar(true)
  }

  build() {
    Navigation(this.navPathStack) {
      Row() {
        Column() {
          Text(this.message)
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
      }
      .height('100%')
    }
    .hideTitleBar(true)
    .navBarWidth('50%')
    .navDestination(this.pageMap)
    .mode(NavigationMode.Auto)
  }
}

export class DfRouter {

....省略代码

  /**
   * @param builderName
   * @param builder
   */
  public static getBuilder(builderName: string): WrappedBuilder<[object]> {
    let builder = DfRouter.builderMap.get(builderName);
    return builder as WrappedBuilder<[object]>;
  }

  ....省略代码
}

上面代码 根据模块名,获取WrappedBuilder对象,通过builder接口创建页面

DfRouter.getBuilder(name).builder(param) 方法是返回了个一个WrapeedBudilder

注册页面路由原来是这样的

复制代码
export default class DfAbilityStage extends AbilityStage{

 onCreate(): void {
    GlobalContext.getContext().setObject("appContext", this.context.getApplicationContext());
    
    this.initRouter();
   
  }


  /**
   * 将entry中所有页面一次性注册进来
   */
  initRouter() {
    let navPathStack: NavPathStack = new NavPathStack()
    GlobalContext.getContext().setObject('entryPageStack', navPathStack);
    DfRouter.createNavPathStack(navPathStack);
  
    // 加载页面
    import('./pages/AdPage');
    import('./pages/HomePage');
    import('./pages/TestAPage');
    import('./webContainer/pages/WebPage');
   
  }

}

  static readonly PAGE_AD: RouterInfo = new RouterInfo('entry', 'AdPage');
  static readonly PAGE_TEST: RouterInfo = new RouterInfo('entry', 'TestPage');


DfRouter.registerRouterPage(RouterInfo.PAGE_WEB, wrapBuilder(getWebPage));

而下面api12 更新了,变成了让人舒服的 理想状态,同时哪些生命周期也有了

复制代码
// 该示例演示NavDestination的生命周期时序。
@Builder
export function PageOneBuilder(name: string, param: Object) {
  PageOneComponent()
}

@Component
struct PageOneComponent {
  private stack: NavPathStack | null = null;
  @State eventStr: string = "";

  build() {
    NavDestination() {
      Column() {
        Text("event: " + this.eventStr)
        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            if (this.stack) {
              this.stack.pushPath({name: "pageOne"});
            }
          })
        Button('pop', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.stack?.pop()
          })
      }
      .width('100%')
      .height('100%')
    }
    .title('pageOne')
    .onAppear(() => { this.eventStr += "<onAppear>"; })
    .onDisAppear(() => { this.eventStr += "<onDisAppear>"; })
    .onShown(() => { this.eventStr += "<onShown>"; })
    .onHidden(() => { this.eventStr += "<onHidden>"; })
    .onWillAppear(() => { this.eventStr += "<onWillAppear>"; })
    .onWillDisappear(() => { this.eventStr += "<onWillDisappear>"; })
    .onWillShow(() => { this.eventStr += "<onWillShow>"; })
    .onWillHide(() => { this.eventStr += "<onWillHide>"; })
    // onReady会在onAppear之前调用
    .onReady((ctx: NavDestinationContext) => {
      try {
        this.eventStr += "<onReady>";
        this.stack = ctx.pathStack;
      } catch (e) {
        console.log(`testTag onReady catch exception: ${JSON.stringify(e)}`)
      }
    })
  }
}

@Entry
@Component
struct NavigationExample3 {
  private stack : NavPathStack = new NavPathStack();

  build() {
    Navigation(this.stack) {
      Stack({alignContent: Alignment.Center}) {
        Button('pushPath', { stateEffect: true, type: ButtonType.Capsule })
          .width('80%')
          .height(40)
          .margin(20)
          .onClick(() => {
            this.stack.pushPath({ name: "pageOne" })
          })
      }
      .width('100%')
      .height('100%')
    }
    .width('100%')
    .height('100%')
    .title('Navigation')
  }
}

注册路由方式也改变了

复制代码
// 工程配置文件module.json5中配置 {"routerMap": "$profile:route_map"}
// route_map.json
{
  "routerMap": [
    {
      "name": "pageOne",
      "pageSourceFile": "src/main/ets/pages/Index.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description": "this is pageOne"
      }
    }
,
    {
      "name": "/modules/scan",
      "pageSourceFile": "src/main/ets/pages/scan/ScanViewPage.ets",
      "buildFunction": "getScanPage",
      "data": {
        "description": "this is pageOne"
      }
    },
  ]
}

版本api12 加了配置文件的映射表不再是动态的了

是不是看着舒服多了,详细内容看api12 文档哈,感觉有用记得点个赞,感谢了!!

相关推荐
遇到困难睡大觉哈哈6 小时前
Harmony os——ArkTS 语言笔记(六):模块、导入导出与 `this` 关键字
笔记·harmonyos·鸿蒙
遇到困难睡大觉哈哈10 小时前
Harmony os ——ArkTS 语言笔记(五):泛型、空安全与可选链
前端·笔记·安全·harmonyos·鸿蒙
遇到困难睡大觉哈哈16 小时前
Harmony Os ArkUI 简易计算器键盘示例
鸿蒙
遇到困难睡大觉哈哈17 小时前
Harmony os LazyForEach:数据懒加载详解
服务器·网络·windows·harmonyos·鸿蒙
遇到困难睡大觉哈哈17 小时前
Harmony os 卡片传递消息给应用(message 事件)详细介绍
java·服务器·javascript·harmonyos·鸿蒙
A懿轩A18 小时前
【2025版 OpenHarmony】 GitCode 口袋工具:Flutter + Dio 网路请求 打造随身的鸿蒙版 GitCode 搜索助手
windows·flutter·华为·鸿蒙·openharmony·开源鸿蒙
jackiendsc19 小时前
基于ESP32实现物联网远程可视化遥控小船的主要过程
物联网·esp32·鸿蒙·遥控
遇到困难睡大觉哈哈20 小时前
Harmony os——ArkTS 语言笔记(七):注解(Annotation)实战理解
java·笔记·ubuntu·harmonyos·鸿蒙
遇到困难睡大觉哈哈20 小时前
Harmony os 卡片页面交互(postCardAction & FormLink)
交互·harmonyos·鸿蒙
威哥爱编程1 天前
【鸿蒙开发案例篇】快速掌握使用NAPI调用C标准库的功能
harmonyos·arkts·arkui