鸿蒙 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 文档哈,感觉有用记得点个赞,感谢了!!

相关推荐
Keya1 天前
在HarmonyOS(鸿蒙)中H5页面中的视频不会自动播放
app·harmonyos·arkts
儿歌八万首1 天前
HarmonyOS中各种动画的使用介绍
华为·harmonyos·arkts·arkui
HarmonyOS小助手1 天前
从航旅纵横到东南亚Grab:鸿蒙生态的“星辰大海”,由开发者共绘
harmonyos·鸿蒙·鸿蒙生态
逻极1 天前
HarmonyOS从入门到精通:自定义组件开发指南(二):组件属性与参数传递
华为·harmonyos·arkts·鸿蒙·自定义组件
HarmonyOS小助手2 天前
在鸿蒙中造梦的开发者,一边回答,一边前行
harmonyos·鸿蒙·harmonyos next·鸿蒙生态
SuperHeroWu73 天前
【HarmonyOS】鸿蒙端云一体化开发入门详解 (一)
华为·harmonyos·鸿蒙·入门·云函数·端云一体化开发·clouddev
Fanmeang3 天前
OSPF路由过滤
运维·网络·华为·ip·路由·ospf·路由过滤
周胡杰3 天前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
simple丶3 天前
【HarmonyOS】封装用户鉴权工具类
harmonyos·arkts·arkui
simple丶3 天前
【HarmonyOS】基于Axios封装网络请求工具类
harmonyos·arkts·arkui