鸿蒙Navigation拦截器实现页面跳转登录鉴权方案详解
我们在进行页面跳转时,很多情况下都得考虑登录状态问题,比如进入个人信息页面,下单交易页面等等。在这些场景下,通常在页面跳转前,会先判断下用户是否已经登录,若已登录,则跳转到相应的目标页面,若没有登录,则先跳转到登录页面,然后等着获取登录状态,若登录页面关闭时,能获取到已登录,则继续跳转到目标页,若用户取消了登录,则终止后面的行为。这样的处理通常会存在一些问题,例如很多页面都与登录状态相关,这样需要在大量的入口处增加登录逻辑判断。即使封装成一个方法,也需要关心是否登录成功,增加了逻辑的复杂性,而且登录页面先关闭,再打开新页面,页面切换动画也很不协调。
那么我们有没有一种更好的方案来处理登录鉴权问题呢?首先我们先梳理一下我们想要的效果,我们的目的是要跳转到相应的目标页,目标页是否需要先登录,我们是不太愿意关注的,最好是内部自己处理掉,,若没有登录,就先进行登录,登录成功后,继续后面的行为,外面使用的地方尽量做到无感知。总结一下就是进行页面跳转时,内部先判断一下状态,然后再进行后续的行为,而这恰好是Navigation拦截器的功能。
Navigation拦截器的介绍与使用
NavPathStack提供了setInterception方法,用于设置Navigation页面跳转拦截回调。该方法需要传一个NavigationInterception对象,该对象包含三个回调函数willShow,didShow和modeChange,我们在willShow页面即将显示时,进行拦截处理。先判断是否登录,没有登录,就重定向到登录页面,若已登录,则继续后续行为,不做拦截。示例如下
@Entry @ComponentV2 struct Index { nav: NavPathStack = new NavPathStack() isLogin: boolean = false aboutToAppear(): void { this.nav.setInterception({ willShow: (from: NavDestinationContext | NavBar, to: NavDestinationContext | NavBar, operation: NavigationOperation, isAnimated: boolean) => { if (typeof to === 'object') { if (isLogin) { AppRouter.popPage() AppRouter.jumpPage('login', undefined) } } } }) } build() { Navigation(this.nav) .hideToolBar(true) .hideTitleBar(true) .height('100%') .width('100%') } }
拦截器细节优化
如何判断是否需要进行拦截
在拦截器中,虽然我们可以进行拦截重定向跳转,但需要考虑的一个问题是什么情况下进行拦截,也就是哪些页面跳转时需要先判断下登录状态。首先想到的是弄一个数组,所有需要登录校验的页面都放到这个数组中。页面跳转时,我们只需要判断下目标页是否在数组中,就可以知道是否需要进行拦截校验登录了。其实思想是对的,只是我们有更简单的实现方式。在系统路由表中,有一个data字段,可以在这个字段中增加一个字段,是否需要登录,在拦截器中先获取目标页中这个参数,只要所有需要登录的页面,都添加了这个字段就可以了。我们以用户信息页为例,配置如下
{ "routerMap": [ { "name": "login", "pageSourceFile": "src/main/ets/pages/login/LoginPage.ets", "buildFunction": "loginBuilder" }, { "name": "user_info", "pageSourceFile": "src/main/ets/pages/user/UserInfoPage.ets", "buildFunction": "userInfoBuilder", "data": { "needLogin": "1" } } ] }
拦截器中获取该字段的方式如下
this.nav.setInterception({ willShow: (from: NavDestinationContext | NavBar, to: NavDestinationContext | NavBar, operation: NavigationOperation, isAnimated: boolean) => { if (typeof to === 'object') { const data = (to as NavDestinationContext).getConfigInRouteMap()?.data if (data !== undefined && (data as object)['needLogin'] === '1' && !AppConstant.hasLogin) { AppRouter.popPage() AppRouter.jumpPage(Pages.login, undefined) } } } })
登录成功后如何获取目标页和页面参数
登录成功后,我们如何知道要跳转到哪个目标页,以及跳转到目标页时所需要的参数呢?我们在跳转到登录页时可以增加2个参数targetPage和targetParam,分别表示要处理的目标页以及相应的参数,若targetPage的值为undefined,则说明登录成功后没有后续操作,若有值,则跳转到这个页面并把相应的参数传过去。在拦截器中,可以通过to.pathInfo.name获取到目标页的名称name以及通过to.pathInfo.param获取到目标页所需要的参数,并把它们赋值给登录页面的targetPage和targetParam就行了。
我们可以发现使用拦截器这种方式,完全符合我们最初的设想,外部调用时不用考虑是否要校验登录状态,由拦截器内部自己处理。登录后也是直接跳转到目标也,没有页面关闭效果。而且是否需要判断登录,只需配置一个字段就行了,非常方便。
到此这篇关于鸿蒙Navigation拦截器实现页面跳转登录鉴权方案的文章就介绍到这了,更多相关鸿蒙Navigation拦截器页面跳转登录鉴权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
提示“处理URL时服务器出错”和“HTTP 500错误“的解决方法
关于提示“处理URL时服务器出错”和“HTTP 500错误“的解决方法,需要的朋友可以参考下。2009-11-11unicode utf-8 gb18030 gb2312 gbk各种编码对比
在修改一个cms的过程当中遇到一个php截取字符串的函数(当然得兼容中英字符了),因为对各种编码的字符范围和字符表示不清楚,感觉一头迷雾,虽然可以直接来调用这个函数2009-05-05XXencode 编码,XX编码介绍、XXencode编码转换原理与算法
这篇文章主要介绍了XXencode 编码,XX编码介绍、XXencode编码转换原理、算法,需要的朋友可以参考下2016-06-06浅谈Visual Studio和Visual Studio Code(VSCode)的区别及如何选择
Visual Studio和VSCode两者都是 Microsoft 制造的,它们有着相似的名称,尽管它们的名字相似,但它们的功能却大不相同,本文主要介绍了Visual Studio和Visual Studio Code(VSCode)的区别,感兴趣的可以了解一下2024-06-06关于idea+centos7+zookeeper报错connectionloss,timeout问题
这篇文章主要介绍了idea+centos7+zookeeper报错connectionloss,timeout问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-01-01
最新评论