HMRouter介绍
HMRouter是HarmonyOS上页面跳转的场景解决方案,主要解决应用内原生页面间相互跳转的问题。本文主要以实际开发中的各项场景为例,介绍HMRouter路由框架的使用。HMRouter路由框架提供了下列功能特性:
- 使用自定义注解实现路由跳转。
- 支持HAR/HSP。
- 支持路由拦截、路由生命周期。
- 简化自定义动画配置:配置全局动画,单独指定某个页面的切换动画。
- 支持不同的页面类型:单例页面、Dialog页面。
该框架底层对Navigation相关能力进行了封装,帮助开发者减少对Navigation相关细节内容的关注、提高开发效率,同时该框架对页面跳转能力进行了增强,例如其中的路由拦截、单例页面等。下文以页面跳转、弹窗提示、转场动效、数据加载、维测场景为切入点,介绍HMRouter路由框架的使用。
页面跳转场景
页面跳转与返回
HMRouter提供了基于自定义注解的页面跳转与返回功能,使用步骤如下:
- 为需要跳转的页面添加@HMRouter注解,并配置其中的pageUrl参数,例如此处配置为ProductContent。
@HMRouter({ pageUrl: 'ProductContent' })
@Component
export struct ProductContent {
// ...
}
- 在需要进行页面跳转的位置,使用HMRouterMgr提供的push/replace方法进行页面跳转,在参数中配置目标页面的pageUrl,param参数等,例如下述代码配置pageUrl为ProductContent,并传递了相关参数。此处也可以配置页面栈唯一标识navigationId,当使用多个HMNavigation时建议开发者手动指定,当使用单个HMNavigation时,开发者可以不传递navigationId参数,系统会默认处理。同时HMRouter对push/replace方法还做了增强,可以传递第二个参数,在其中配置返回到当前页面时数据接受的回调函数onResult,只要有页面返回到该页面时都会触发该函数,该函数会接收一个参数,可以通过该参数上的srcPageInfo.name获取到由哪个页面跳转到当前页,还可以从该参数上的result属性获取到其他页面pop到当前页面时传递的参数。
HMRouterMgr.push({
navigationId: "mainNavigationId",
pageUrl: 'ProductContent',
param: { a: 1, b: 2 },
animator: new CustomAnimator(),
}, {
onResult(popInfo: HMPopInfo) {
const pageName = popInfo.srcPageInfo.name;
const params = popInfo.result;
console.log(`page name is ${pageName}, params is ${JSON.stringify(params)}`);
}
})
- 在跳转的目标页面使用HMRouterMgr.getCurrentParam()获取到传递的页面参数。
@Component
export struct ProductContent {
// ...
@State param: ParamsType | null = null;
aboutToAppear(): void {
this.param = HMRouterMgr.getCurrentParam() as ParamsType;
}
// ...
}
-
如需使用页面返回功能,在对应的业务逻辑位置使用HMRouterMgr提供的pop方法实现页面返回,同样的pop方法支持传入navigationId,同时HMRouter还支持在返回时通过配置param参数向其所返回的页面传递参数。
HMRouterMgr.pop({ navigationId: 'mainNavigationId', param: this.param })
多次页面跳转,返回指定页面
当页面跳转路径如HomePage->PageA->PageB->PageC,开发者希望在PageC的页面逻辑中直接返回到HomePage并携带参数,开发者仅需使用HMRouterMgr提供的pop方法,传入要返回目标页面的pageUrl、传递的参数param,即可直接带参返回到指定页面。
HMRouterMgr.pop({ navigationId: 'mainNavigationId', pageUrl: 'HomePage', param: this.param })
图1 返回指定页面示意图
应用未登录,点击跳转登录页的校验场景
应用中经常会有当用户未登录应用时,点击某些应用内容会自动跳转到登录页面的场景,在使用HMRouter对此场景进行实现时,可以采用以下步骤:
-
定义拦截器类LoginCheckInterceptor实现IHMInterceptor接口。
-
为定义的拦截器类添加@HMInterceptor注解,通过interceptorName配置拦截器名称LoginCheckInterceptor。
-
实现IHMInterceptor的handle方法,在该方法中根据当前的登录状态来控制页面跳转的目标。
-
当用户已登录,通过返回HMInterceptorAction.DO_NEXT,正常执行后续页面跳转逻辑。
-
当用户未登录,通过Toast弹窗向用户提示登录,然后跳转到登录页面,最后通过HMInterceptorAction.DO_REJECT来拦截此次跳转请求。
-
@HMInterceptor({ interceptorName: 'LoginCheckInterceptor' })
export class LoginCheckInterceptor implements IHMInterceptor {
handle(info: HMInterceptorInfo): HMInterceptorAction {
// ...
if (!!AppStorage.get('isLogin')) {
return HMInterceptorAction.DO_NEXT;
} else {
info.context.getPromptAction().showToast({ message: '请先登录' })
HMRouterMgr.push({
pageUrl: 'loginPage',
param: info.targetName,
skipAllInterceptor: true
})
return HMInterceptorAction.DO_REJECT;
}
// ...
}
}
- 在需要进行拦截的页面中配置@HMRouter的interceptors参数即可,由于一个页面可以配置多个拦截器,所以需要将关联的拦截器名称封装为一个数组进行传入。
@HMRouter({
pageUrl: 'shoppingBag',
singleton: true,
interceptors: ['LoginCheckInterceptor'],
lifecycle: 'requestLifecycle'
})
@Component
export struct ShoppingBagContent {
// ...
}
运行效果如下图所示。