# 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) ,请自由的享受和参与开源。