猫窝私语 — Makumo's Blog

玛酷猫的温馨小窝,记录生活点点滴滴。

@玛酷猫9月前

02/16
16:33
其他

Ionic 3 升级 Ionic 4 迁移踩坑系列(四)

路由
Ionic4整体舍弃了Ionic3中的使用IonicPage设置路由地址的方法,而完全使用Angular的路由器(虽然在ionic3中也可以使用Angular路由,不过之前项目都是使用Ionic3的路由方法)
在初始化的项目结构目录里src/app/app-routing.module.ts文件,一个简单的结构类似下方:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PermissionGuard, WelcomeGuard } from './guard/';

const routes: Routes = [
  { path: '', redirectTo: '/welcome', pathMatch: 'full' },
  { path: '', canActivate: [PermissionGuard], children: [
    { path: 'app', loadChildren: './pages/tabs/tabs.module#TabsPageModule' },
  ]},
  { path: 'welcome', canActivate: [WelcomeGuard], loadChildren: './pages/welcome/welcome.module#WelcomePageModule' },
  { path: 'sign-in', loadChildren: './pages/sign-in/sign-in.module#SignInPageModule' }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

在这个简单结构中包含一个tabs主模块,一个欢迎页,一个登录认证页面。用户第一次访问时,由第一条路由配置导向欢迎页,在欢迎页的配置上有路由守卫(Route guards)的设置,用来判断是否第一次访问,如果不是则引导到主模块,在主模块上同样配置一个路由守卫,用来检验用户权限,如权限不正确则引导到登录页面。此外路由不仅可以配置在总的路由配置文件中,也可以配置在各级子模块中,一方面清晰模块关系,同时也方便模块的添加和移动。路由相关配置也有很多,详情可以参考官方文档,这里是传送门

路由守卫
在Ionic3中,使用ionViewCanEnter和ionViewCanLeave实现Route guards的功能,而在Ionic4中,由于使用Angular的路由,同样也使用其对应的路由接口,在官方文档中,有5种接口,分别是

CanActivate to mediate navigation to a route.
CanActivateChild to mediate navigation to a child route.
CanDeactivate to mediate navigation away from the current route.
Resolve to perform route data retrieval before route activation.
CanLoad to mediate navigation to a feature module loaded asynchronously.

在上面的例子中,使用了两个路由守卫用来判断是否第一次访问和是否具有用户权限,其中判断初次访问的例子如下

import { Injectable } from '@angular/core';
import { Router, CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { Storage } from '@ionic/storage';

@Injectable({
  providedIn: 'root'
})
export class WelcomeGuard implements CanActivate {

  constructor(public router: Router, private storage: Storage) {}

  async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    const first = await this.storage.get('firstIn');
    if (first) {
      this.router.navigateByUrl('app/tabs/(home:home)');
    }
    return !first;
  }
}

在路由守卫中判断本地存储中是否存在首次访问的标识,有的话就直接进入tabs模块的home子模块。更多详细用法,同样参见官网文档,传送门

Ionic 3 升级 Ionic 4 迁移踩坑系列(四)