# URLRouter **Repository Path**: ipad4/urlrouter ## Basic Information - **Project Name**: URLRouter - **Description**: 鸿蒙开发URL模式动态路由跳转 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-08-19 - **Last Updated**: 2024-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # URLRouter ## 简介 在 iOS 或者 Android 开发的时候,一般都会有一套统一的URL规范跳转,通过URL路径可以跳转到不同的App原生页面。类似iOS的`MGJRouter`,Android的`ARouter`。 主要场景就是可以通过后台在App配置一些资源位,在App内所有的资源位通过URL路径可以跳转到App的任何页面;并且保持iOS、Android、HarmoneyOS三端跳转规则保持一致。
比如在App的首页Banner,需要跳转到某个商品详情页面,iOS/Android 的统一配置路径为: ```html hbh://mall/store/detail?storeId=88888 ``` - `hbh`为App 自定义的`URLScheme`,每个App都需要自定义自己的`Scheme`。 - `mall/store/detail`为路径 - `storeId` 为参数 所以在鸿蒙 `HarmoneyOS Next` 开发中,我们需要继续沿用这套规范,通过 URL 跳转到不同的页面,且要保证 iOS、Andorid、HarmoneyOS Next 的跳转规则一致。 同时可以解决使用组件化开发,如果两个业务组件需要相互跳转到对应组件模块的页面,就需要相互引用组件,这样就会造成依赖循环引用的问题。 所以,为了规范跳转规则,避免造成循环引用的问题,在页面跳转的时候,我们尽量直接通过路由的方式跳转,模块库直接尽量减少相互依赖,业务模块也全部依赖 Router 组件即可。
## 下载安装 ```shell ohpm install @gg/urlrouter ``` ## 使用说明 ### HAP主项目配置 在App入口配置类一般为 `EntryAbility.ets`文件配置: ```extendtypescript // 导入 import { URLRouter } from '@gg/urlrouter' onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 设置自定义Scheme,如:hbh URLRouter.configAppScheme('hbh') } ``` 拦截器配置(可选实现),拦截后可以自定义跳转逻辑,`return false` 会中断组件内部跳转: ```extendtypescript // 拦截器,如果某个URL需要自定义处理,返回false中断内部跳转 URLRouter.getInstance().shouldLoadUrlHandler = ((url):boolean => { // 比如要拦截http链接跳转到浏览器 if (url.startsWith('http')) { // ... 代码省略(跳转到浏览器加载URL) // URLRouter.openUrl('hbh://wap', {'url': url}) return false // false拦截 } return true }); ``` 未跳转成功或未找到页面回调配置(可选实现),此处可以设置跳转到指定兜底404页面 ```extendtypescript // 跳转失败回调闭包 URLRouter.getInstance().pushFailHandler = ((err):void => { if (err) { // 代码省略(跳转到自定义的404未找到页面) // URLRouter.openUrl('hbh://base/notfound') console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`); } }); ``` ### 页面所在组件配置 一般业务组件,建议使用 HSP动态库模式开发,HAR静态库模式同样支持。 组件内创建的页面,通过`@Entry({routeName: "url_page"})`的方式创建页面入口。 举例我们创建HSP动态组件商城模块`hbhshop`,组件内创建一个页面店铺详情页面:`StoreDetailPage.ets` ```extendtypescript import router from '@ohos.router'; // 申明页面入口时,添加路由名称,名称和路径定义保持一致即可 @Entry({routeName: "mall/store/detail"}) @Component export struct StoreDetailPage { // 接收Router参数 @State storeId: string = ''; // 或 // @State storeId: string = (router.getParams() as Record).storeId; // 或 // @State storeId: string = (router.getParams() as Record)['storeId']; // aboutToAppear函数在创建自定义组件的新实例后,在执行其build函数之前执行 aboutToAppear(): void { // 为了增加兼容性,建议在 aboutToAppear 判空赋值 const routerParams = (router.getParams() as Record); if (routerParams) { if (routerParams.storeId) { this.storeId = routerParams.storeId; } } } build() { Row() { Column() { Text(`这是 hbhshop 组件模块`) .fontSize(30) .fontWeight(FontWeight.Bold) Text(`来到了storeId为${this.storeId}的店铺`) .fontSize(20) .fontWeight(FontWeight.Regular) .margin({ top:15 }) } .width('100%') } .height('100%') } } ``` - router路径定义:,`@Entry({routeName: "mall/store/detail"})`;
- 参数接收:`(router.getParams() as Record).storeId;`
这里注意Router参数类型为`Record`。
建议将参数解析写到`aboutToAppear`方法内,并处理为空判断;`aboutToAppear`函数在创建自定义组件的新实例后,在执行其build函数之前执行。`aboutToAppear`不同于`onPageShow`的地方在于该函数仅会在自定义组件实例创建后执行一次。 最后在`hbhshop`组件根目录的`Index.ets`对外暴露页面即可: ```typescript export { StoreDetailPage } from './src/main/ets/components/pages/ShopDetailPage' ``` 或 ```typescript import './src/main/ets/pages/StoreDetailPage' ``` 业务组件配置完成! ### HAP主项目依赖设置 为了避免组件的循环依赖问题,所有路由需要跳转到的页面或者组件模块都需要在 HAP主项目中依赖。
这里拿上面 `hbhshop`动态模块举例: 1. 添加依赖 在`HAP`主项目`entry`模块中,`oh-package.json5`添加依赖: ```json5 "dependencies": { 'hbhshop': "file:../hbhshop" } ``` 2. 引入组件页面 ```typescript import 'hbhshop' ``` 如果场景是动态配置的,不知道在什么时机引入合适,可以直接写到App的模块入口`EntryAbility.ets`中,只要保证跳转之前引用过模块即可! 3. 跳转 ```typescript // 导入Router import { URLRouter } from '@gg/urlrouter' ``` ```extendtypescript URLRouter.openUrl('hbh://mall/store/detail?storeId=88888') ``` 或 ```extendtypescript URLRouter.openUrl('hbh://mall/store/detail', { 'storeId':'88888' }) ``` 或 ```extendtypescript URLRouter.openRouterName('mall/store/detail', { 'storeId':'88888' }) ``` 同样如果其他业务组件需要相互跳转,在业务组件中添加 `@gg/urlrouter`依赖: ```shell ohpm install @gg/urlrouter ``` 这里需要注意的是,业务组件之间不需要相互依赖,业务组件只依赖 `urlrouter`,对于业务组件的依赖和引入,全部放到`HAP`主项目 `entry`模块中。 ## 开源协议 本项目基于 [MIT license](LICENSE.txt) ,请自由的享受和参与开源。