When we make page jumps, we have to consider the login status in many cases, such as going to the personal information page, order transaction page, etc. In these cases, we usually determine whether the user is logged in or not before jumping to the corresponding target page. In these scenarios, we usually determine whether the user is logged in before the page jump, if he/she is logged in, the page jumps to the corresponding target page, if he/she is not logged in, the page jumps to the login page first, and then waits for the login status to be obtained, if the login page closes with the logged in status, then the page jumps to the target page, and if the user cancels his/her login, then the behavior will be terminated. There are usually some problems with this kind of processing, such as many pages are related to the login status, which requires adding login logic judgment at a large number of entry points. Even if it is encapsulated into a single method, it still needs to care whether the login is successful or not, which increases the complexity of the logic, and the page switching animation is also very uncoordinated when the login page is closed first and then a new page is opened.
So do we have a better program to deal with the login authentication problem? First of all, let's sort out the effect we want, our purpose is to jump to the corresponding target page, whether the target page needs to be logged in first, we are not willing to pay attention to, it is best to deal with their own internal, if not logged in, then log in, logged in successfully, to continue the behavior of the back, outside the use of the place as far as possible to achieve non-perceptual. To summarize, when you make a page jump, you should first judge the state internally, and then proceed with the subsequent behavior, which is exactly the function of the Navigation interceptor.
Introduction and Use of Navigation Interceptor
NavPathStack provides setInterception method to set Navigation page jump interception callback. This method needs to pass a NavigationInterception object, which contains three callback functions willShow, didShow and modeChange, we intercept the willShow page when it is about to be displayed. First determine whether you are logged in or not, if you are not logged in, redirect to the login page, if you are logged in, then continue the subsequent behavior without interception. The example is as follows
@Entry
@ComponentV2
struct Index {
nav: NavPathStack = new NavPathStack()
isLogin: boolean = false
aboutToAppear(): void {
({
willShow: (from: NavDestinationContext | NavBar, to: NavDestinationContext | NavBar,
operation: NavigationOperation, isAnimated: boolean) => {
if (typeof to === 'object') {
if (isLogin) {
()
('login', undefined)
}
}
}
})
}
build() {
Navigation()
.hideToolBar(true)
.hideTitleBar(true)
.height('100%')
.width('100%')
}
}
Interceptor detail optimization
How to determine if an interception is required
In the interceptor, although we can intercept the redirection jump, but need to consider the question of what circumstances to intercept, that is, which pages need to jump to determine the login status. The first thing that comes to mind is to make an array of all the pages that need login verification and put them into this array. When the page jumps, we only need to judge whether the target page is in the array, we can know whether we need to intercept the login check. In fact, the idea is right, but we have a simpler way to implement it. In the system routing table, there is a data field, you can add a field in this field, whether you need to log in or not, in the interceptor first get the target page in this parameter, as long as all the pages that need to log in, have added this field. Let's take the user information page as an example and configure it as follows
{
"routerMap": [
{
"name": "login",
"pageSourceFile": "src/main/ets/pages/login/",
"buildFunction": "loginBuilder"
},
{
"name": "user_info",
"pageSourceFile": "src/main/ets/pages/user/",
"buildFunction": "userInfoBuilder",
"data": {
"needLogin": "1"
}
}
]
}
The way to get this field in the interceptor is as follows
({
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' && !) {
()
(, undefined)
}
}
}
})
How to get the target page and page parameters after successful login
After successful login, how do we know which target page to jump to and what parameters are needed to jump to the target page? We can add two parameters targetPage and targetParam when jumping to the login page, which represent the target page to be processed and the corresponding parameters, if the value of targetPage is undefined, it means there is no subsequent operation after successful login, if there is a value, it will jump to this page and pass the corresponding parameters to it. In the interceptor, you can get the name of the target page and the parameters needed by the target page, and assign them to the targetPage and targetParam of the login page.
We can find that the use of interceptors this way, fully consistent with our original idea, the external call do not have to consider whether to check the login status, by the interceptor internal own processing. After logging in, it is also a direct jump to the target as well, no page closure effect. And whether you need to determine the login, just configure a field on the line, very convenient.