手记

路由之路由守卫

基本概念

Angular 的路由守卫指的是,从一个路径跳转到另一个路径之前,执行指定的逻辑,并根据执行结果来决定是否进行跳转。
最典型的例子就是,只有在登录页面填写正确的账号和密码,才被允许导航到内容页面,否则不会进行跳转。

激活拦截

为了实现这个功能,Angular 提供了激活拦截的功能,也就是当路由被激活时,将获得通知。

项目截图:

首先,创建一个权限服务,该服务实现路由守卫的 canActivate() 接口类,当该方法返回 true 时,表示允许跳转;反之则表示不允许跳转。

auth-gurd.service.ts

import { Injectable } from '@angular/core';

// 导入使用到的接口
import {
  Router,
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  UrlTree
} from '@angular/router';
import { Observable } from 'rxjs';

@Injectable()

// 实现 CanActivate 接口
export class AuthGurdService implements CanActivate {

  constructor(
    private router: Router
  ) { }

  canActivate(route: ActivatedRouteSnapshot, // 激活路由的配置项
              state: RouterStateSnapshot) // 路由状态的配置项
              // 函数返回值可以是 boolean、UrlTree、Observable、Promise
              : boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {

              console.log(route);
              console.log(state);
              return this. checkLogin();

  }

  checkLogin(){
    if (localStorage.getItem('name') && localStorage.getItem('password')) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

}

然后,为了使用这个路由守卫,注入该服务并在路由配置中使用该服务:

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

// 导入路由守卫
import { AuthGurdService } from './common/auth/auth-gurd.service';

const routes: Routes = [
  { path: '', redirectTo: '/login', pathMatch: 'full' },
  {
    path: 'login',
    loadChildren: () => import('./login/login.module').then((m) => m.LoginModule),
  },

  // 在 canActivate 属性中配置路由守卫
  {
    path: 'main',
    canActivate: [AuthGurdService],
    loadChildren: () => import('./main/main.module').then((m) => m.MainModule),
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  
  // 注入路由守卫
  providers: [AuthGurdService],
})
export class AppRoutingModule { }

现在,在浏览器中打开该应用时,我们可以看到登录页面。
在表单中输入账号密码,点击登录按钮,将会跳转至内容页面,否则什么也不会发生。

*上面的例子中,路由守卫的方法 canActivate(),除了返回布尔值还可以返回 Observable 和 Promise 对象,这两个对象使得路由守卫可以根据异步处理结果来进行判断。

canActivate(route: ActivatedRouteSnapshot,
            state: RouterStateSnapshot)
            : boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
              
    return new Promise((done, fail) => {

              setTimeout(()=>{
                if(this.checkLogin()){
                  done(true);
                }else{
                  fail(false);
                }
              },2000);

            });
}

数据预加载拦截与模块加载拦截

除了上面介绍的激活拦截,Angular 还提供了数据预加载拦截(实现 Resolve 接口)和模块加载拦截(实现 Canload 接口)。
数据预加载拦截适用于对数据进行预加载,当确认数据加载成功后,再激活目标组件。
模块加载拦截适用于惰性加载的路由配置,当路径匹配到该路由时,动态判断是否对该模块进行加载。
数据预加载拦截与模块加载拦截在实际工作中,应用较少,在此就不展开了。


end

0人推荐
随时随地看视频
慕课网APP