页面跳转时,登录状态几乎是绕不开的坎儿。比如进入个人信息页、下单页面,这些场景下,通常得先判断用户是否登录。如果已登录,直接跳转;没登录,就先拉到登录页,等登录成功后,再继续跳转。如果用户取消登录,那就终止。这种处理方式,看起来逻辑清晰,但实际用起来问题不少。

最大的麻烦在于:很多页面都需要登录状态,于是要在大量入口处塞入登录判断逻辑。就算封装成一个方法,调用方还是得关心登录是否成功,逻辑复杂度降不下来。更别提登录页先关掉,再打开新页面,切换动画也显得很突兀,体验上不太流畅。

那么,有没有更好的方案呢?先梳理一下期望的效果:我们的目标是跳转到目标页,至于目标页是否需要登录,最好由内部自己处理,外部调用时无感知。总结下来就是——页面跳转时,内部先判断状态,再做后续行为。而这,恰好是 Na vigation 拦截器擅长的事。

Na vigation拦截器的介绍与使用

Na vPathStack 提供了一个 setInterception 方法,用来设置页面跳转拦截回调。这个方法需要传一个 Na vigationInterception 对象,包含三个回调:willShow、didShow 和 modeChange。我们主要在 willShow 里做拦截处理——页面即将显示时,判断是否已登录,没登录就重定向到登录页,已登录则放行。

@Entry@ComponentV2struct Index {  na v: Na vPathStack = new Na vPathStack()  isLogin: boolean = false  aboutToAppear(): void {    this.na v.setInterception({      willShow: (from: Na vDestinationContext | Na vBar, to: Na vDestinationContext | Na vBar,        operation: Na vigationOperation, isAnimated: boolean) => {        if (typeof to === 'object') {          if (isLogin) {            AppRouter.popPage()            AppRouter.jumpPage('login', undefined)          }        }      }    })  }  build() {    Na vigation(this.na v)    .hideToolBar(true)    .hideTitleBar(true)    .height('100%')    .width('100%')  }}

拦截器细节优化

如何判断是否需要进行拦截

拦截器里能拦截重定向,但一个关键问题是:哪些页面需要拦截?最简单的想法是弄个数组,把所有需要登录校验的页面放进去,跳转时判断目标页是否在数组中。思路没错,但还有更简单的实现方式。系统路由表里有一个 data 字段,可以在里面加一个标记,比如 needLogin。拦截器里先获取目标页的这个参数,所有需要登录的页面,都加上这个字段就行。以用户信息页为例:

{  "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.na v.setInterception({  willShow: (from: Na vDestinationContext | Na vBar, to: Na vDestinationContext | Na vBar,    operation: Na vigationOperation, isAnimated: boolean) => {    if (typeof to === 'object') {      const data = (to as Na vDestinationContext).getConfigInRouteMap()?.data      if (data !== undefined && (data as object)['needLogin'] === '1' && !AppConstant.hasLogin) {        AppRouter.popPage()        AppRouter.jumpPage(Pages.login, undefined)      }    }  }})

登录成功后如何获取目标页和页面参数

登录成功后,怎么知道要跳回哪个目标页,以及需要什么参数呢?很简单——跳转到登录页时,带上两个参数 targetPage 和 targetParam,分别表示目标页和参数。如果 targetPage 是 undefined,说明登录后没有后续操作;否则就跳转过去,并把参数带上。在拦截器里,可以通过 to.pathInfo.name 拿到目标页名称,通过 to.pathInfo.param 拿到目标页参数,然后塞给登录页的 targetPage 和 targetParam 就行。

使用拦截器这种方式,完全符合最初的设想:外部调用不用关心是否要校验登录,由拦截器内部处理。登录后直接跳转到目标页,没有页面切换的突兀感。而且是否需要判断登录,只需在路由表里加一个字段,非常方便。

本文转载于:https://www.jb51.net/program/330855i92.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。