Angular 入坑记录的笔记第六篇,介绍 Angular 路由模块中关于路由守卫的相关知识点,了解常用到的路由守卫接口,知道如何通过实现路由守卫接口来实现特定的功能需求,以及实现对于特性模块的惰性加载
对应官方文档地址:
配套代码地址:angular-practice/src/router-combat
二、ContentsAngular 从入坑到弃坑 - Angular 使用入门
Angular 从入坑到挖坑 - 组件食用指南
Angular 从入坑到挖坑 - 表单控件概览
Angular 从入坑到挖坑 - HTTP 请求概览
Angular 从入坑到挖坑 - Router 路由使用入门指北
Angular 从入坑到挖坑 - 路由守卫连连看
三、Knowledge Graph 四、Step by Step 4.1、基础准备重复上一篇笔记的内容,搭建一个包含路由配置的 Angualr 项目
新建四个组件,分别对应于三个实际使用到的页面与一个设置为通配路由的 404 页面
-- 危机中心页面 ng g component crisis-list -- 英雄中心页面 ng g component hero-list -- 英雄相亲页面 ng g component hero-detail -- 404 页面 ng g component page-not-found在 app-routing.module.ts 文件中完成对于项目路由的定义,这里包含了对于路由的重定向、通配路由,以及通过动态路由进行参数传递的使用
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; // 引入组件 import { CrisisListComponent } from './crisis-list/crisis-list.component'; import { HeroListComponent } from './hero-list/hero-list.component'; import { HeroDetailComponent } from './hero-detail/hero-detail.component'; import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; const routes: Routes = [ { path: 'crisis-center', component: CrisisListComponent, }, { path: 'heroes', component: HeroListComponent, }, { path: 'hero/:id', component: HeroDetailComponent, }, { path: '', redirectTo: '/heroes', pathMatch: 'full', }, { path: '**', component: PageNotFoundComponent, } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) export class AppRoutingModule { }之后,在根组件中,添加 router-outlet 标签用来声明路由在页面上渲染的出口
<h1>Angular Router</h1> <nav> <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a> <a routerLink="/heroes" routerLinkActive="active">Heroes</a> </nav> <router-outlet></router-outlet> 4.2、路由守卫在 Angular 中,路由守卫主要可以解决以下的问题
对于用户访问页面的权限校验(是否已经登录?已经登录的角色是否有权限进入?)
在跳转到组件前获取某些必须的数据
离开页面时,提示用户是否保存未提交的修改
Angular 路由模块提供了如下的几个接口用来帮助我们解决上面的问题
CanActivate:用来处理系统跳转到到某个路由地址的操作(判断是否可以进行访问)
CanActivateChild:功能同 CanActivate,只不过针对的是子路由
CanDeactivate:用来处理从当前路由离开的情况(判断是否存在未提交的信息)
CanLoad:是否允许通过延迟加载的方式加载某个模块
在添加了路由守卫之后,通过路由守卫返回的值,从而达到我们控制路由的目的
true:导航将会继续
false:导航将会中断,用户停留在当前的页面或者是跳转到指定的页面
UrlTree:取消当前的导航,并导航到路由守卫返回的这个 UrlTree 上(一个新的路由信息)
4.2.1、CanActivate:认证授权在实现路由守卫之前,可以通过 Angular CLI 来生成路由守卫的接口实现类,通过命令行,在 app/auth 路径下生成一个授权守卫类,CLI 会提示我们选择继承的路由守卫接口,这里选择 CanActivate 即可
ng g guard auth/auth在 AuthGuard 这个路由守卫类中,我们模拟了是否允许访问一个路由地址的认证授权。首先判断是否已经登录,如果登录后再判断当前登录人是否具有当前路由地址的访问权限
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { /** * ctor * @param router 路由 */ constructor(private router: Router) { } canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { // 判断是否有 token 信息 let token = localStorage.getItem('auth-token') || ''; if (token === '') { this.router.navigate(['/login']); return false; } // 判断是否可以访问当前连接 let url: string = state.url; if (token === 'admin' && url === '/crisis-center') { return true; } this.router.navigate(['/login']); return false; } }