鸿蒙next开发:Navigation页面跳转

652 篇文章 5 订阅
647 篇文章 7 订阅

场景:多har包之间的页面跳

A.har中的A需要跳转到B.har的B中,由于A.har与B.har之间由不同业务开发,互相隔离。如果A.har要跳转到B.har,必然需要配置依赖,引入B.har。如果B.har开发不完善或存在运行bug,就必然影响互相开发效率。

如下图所示:

鸿蒙官方给的解决方案:提升两个包之间的互相依赖到另一个共用路由模块中。如果对android开发熟悉的小伙伴,可能想到了jetpack中同名的库。依赖方案如下图所示:

逻辑实现

路由模块的实现

RouterModule模块包括:全局路由栈(NavPathStack)和路由表信息(Map)。

  1. 路由栈及路由表
export class RouterModule {
    // WrapperBuilder 支持@Builder描述的组件,以参数形式进行封装存储
    static buildMap: Map<string, WrapperBuilder<[object]>> = new Map<string, WrapperBuilder<[object]>>()
    // 路由栈,会关联Navigtion组件
    static navPathStack: NavPathStack = new NavPathStack()
}
  1. 注册页面组件到路由表,以及获取路由页面
 
export class RouterModule {
    public static registerBuilder(builderName: string, builder: WrapperBuilder<[object]>): void {
        RouterModule.buildMap.set(builderName, builder)
    }

    public static getBuilder(builderName: string): WrapperBuilder<[object]> {
        const builder = RounterModule.builderMap.get(builderName)
        if (!builder) {
            // not found builder
        }
        return builder as WrapperBuilder<[object]>
    }
}

  1. 路由跳转
 
export class RouterModule {
    // 通过获取页面栈跳转到指定页面
    public static async push(harName: string, builderName: string): Promise<void> {
        // 动态导入页面所在har模块,避免业务har模块中显示依赖其他har模块,实现按需加载
        await import(harName);
        // 通过路由栈的方法,按路由名字进行路由跳转
        RouterModule.navPathStack.pushPathByName(builderName, null);
    }
}

补充:个人理解,这个模块应该算是Navigation的组件模块之一,但不知道为什么需要开发者自己去实现。

页面跳转实现

  1. 工程主模块加入RouterModule模块,和需要路由的har模块
// Entry.hap中的oh-package.json5文件
"dependencies": {
  "@ohos/routermodule": "file:../RouterModule",
  "@ohos/hara": "file:../harA",
  "@ohos/harb": "file:../harB"
}

  1. 由主工程关联上路由
struct EntryHap {
    @State entryHapARouter: NavPathStack = new NavPathStack();

    aboutToAppear() {
        if (!this.entryHapARouter) {
            this.entryHapARouter = new NavPathStack();
        }
        RouterModule.createRouter('EntryHapA_Router', this.entryHapARouter);
    };

    @Builder
    routerMap(builderName: string, param: object) {
        // 从RouterModule中获取全局路由表
        RouterModule.getBuilder(builderName).builder(param);
    }

    build() {
        // 绑定RouterModule中路由栈
        Navigation(RouterModule.navPathStack) {
            // ...
        }
        .navDestination(this.routerMap); // 从RouterModule中获取全局路由表
    }
}

  1. 在harB中声明需要跳转的页面,并且调用registerBuilder接口将页面注册到RouterModule模块的全局路由表上。以下注册逻辑会在harB的B1页面被首次加载时触发
 
// harB模块的B1页面
@Builder
export function harBuilder(value: object) {
  NavDestination() {
    Column() {
      // ...
    }
  }
}

// 在页面首次加载时触发执行
let builderName = 'B1';
// 避免重复注册
if (!RouterModule.getBuilder(builderName)) {
  // 通过系统提供的wrapBuilder接口封装@Builder装饰的方法,生成harB1页面builder
  let builder: WrappedBuilder<[object]> = wrapBuilder(harBuilder);
  // 注册harB1页面到全局路由表
  RouterModule.registerBuilder(builderName, builder);
}

  1. 动态加载,harB对外提供导出类index.ets,定义加载初始化函数。
export function harInit(name: string): void {
  // 根据routerModule中路由表的key值动态加载要跳转的页面的相对路径
  switch (name) {
    case "B1":
      import("./src/main/ets/components/mainpage/B1");
      break;
    case "B2":
      import("./src/main/ets/components/mainpage/B2");
      break;
    case "B3":
      import("./src/main/ets/components/mainpage/B3");
      break;
    default:
      break;
  }
}

  1. 在harA模块中的A1页面调用RouterModule模块的push方法实现跳转到harB的B1页面。当harB的B1页面被首次通过push方法跳转时,会动态加载B1页面,并且触发步骤3中B1页面的路由注册逻辑,把B1页面注册到RouterModule的全局路由表builderMap中
 
@Builder
export function harBuilder(value: object) {
    NavDestination() {
        Column() {
            Button($r("app.string.to_harb_page1"), { stateEffect: true, type: ButtonType.Capsule })
                .onClick(() => {
                    // 首次调用B1的push时,会动态加载B1页面并且触发页面注册逻辑
                    RouterModule.push('@ohos/harb/src/main/ets/components/mainpage/B1', 'B1');
                })
        }
        .width('100%')
        .height('100%')
    }
        .title('A1Page')
        .onBackPressed(() => {
            RouterModule.pop(RouterNameConstants.ENTRY_HAP);
            return true;
        })
}

说明:步骤3中是在builder中才完成页面的注册,而在步骤4的注册阶段这里,调用push时,采用动态加载的页面加载的方式,触发了builder方法,完成了注册。



最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

鸿蒙HarmonyOS Next全套学习资料←点击领取!(安全链接,放心点击

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

HarmonyOS Next 最新全套视频教程

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

大厂面试必问面试题

鸿蒙南向开发技术

鸿蒙APP开发必备

鸿蒙生态应用开发白皮书V2.0PDF

获取以上完整鸿蒙HarmonyOS学习资料,请点击→

纯血版全套鸿蒙HarmonyOS学习资料

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

在 `next.js` 和 `next/navigation` 中,您可以使用编程式导航来手动跳转到其他页面并携带参数。下面是一些常见的方法: 1. 使用 `next/router` 模块的 `push()` 函数:您可以使用 `push()` 函数来将用户导航到其他页面,并携带查询参数或路由参数。例如,以下示例演示如何使用 `push()` 函数在 `onClick` 事件中手动导航到 `/post` 页面并携带 `id=123` 查询参数: ``` import { useRouter } from 'next/router' function handleClick() { const router = useRouter() router.push({ pathname: '/post', query: { id: '123' } }) } export default function Home() { return ( <div> <h1>Home page</h1> <button onClick={handleClick}>Go to Post</button> </div> ) } ``` 2. 使用 `next/link` 组件的 `href` 属性:您可以使用 `next/link` 组件的 `href` 属性来创建链接,并在需要时手动触发导航。例如,以下示例演示如何使用 `next/link` 组件在 `onClick` 事件中手动导航到 `/post` 页面并携带 `id=123` 查询参数: ``` import Link from 'next/link' function handleClick() { window.location.href = '/post?id=123' } export default function Home() { return ( <div> <h1>Home page</h1> <Link href='/post?id=123'> <a>Go to Post</a> </Link> <button onClick={handleClick}>Go to Post</button> </div> ) } ``` 综上所述,`next.js` 和 `next/navigation` 提供了多种方法来手动跳转到其他页面并携带参数。您可以根据自己的需求选择最适合的方法来实现导航。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值