【硬核解说】一口气讲明白Angular的5种路由守卫RouteGuard是嘛玩意儿

简介: 【硬核解说】一口气讲明白Angular的5种路由守卫RouteGuard是嘛玩意儿


Angular的常用路由守卫有5种,按照执行顺序:

① CanLoad:进入到当前路由的时候触发(若用户没有权限访问,相应的模块并不会被加载。这里是指对应组件的代码)。

CanAcitivate:进入到当前路由的时候触发(即使返回的是false,用户并没有权限访问该路由,但是相应的模块会被加载)。

③ CanActivateChild:刚刚进入子路由触发。

Resolve:进入当前路由之后,离开之前触发。

CanDeactivate:离开当前路由离开的时候触发。

① guard/CanLoad.guard.ts

import { Injectable } from '@angular/core';
import { CanLoad, Route, Router, UrlSegment } from '@angular/router';
@Injectable()
export class CanLoadGuard implements CanLoad {
    constructor(private router: Router) { }
    canLoad(
        route: Route,
        segments: UrlSegment[]
    ) {
        console.log('【CanLoad守卫:进入当前子路由】----------------------------------------', route, segments);
        return true;//进入路由
        // return false;//中端路由
    }
}

② guard/CanAcitivate.guard.ts

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
@Injectable({ providedIn: 'root' })//这个在该守卫里面必须要,其余两种守卫中可以不需要
/* 没有上面这句会报错
ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[CanAcitivateGuard -> CanAcitivateGuard -> CanAcitivateGuard]: 
NullInjectorError: No provider for CanAcitivateGuard!
NullInjectorError: R3InjectorError(AppModule)[CanAcitivateGuard -> CanAcitivateGuard -> CanAcitivateGuard]: 
NullInjectorError: No provider for CanAcitivateGuard! */
export class CanAcitivateGuard implements CanActivate {
    constructor(private router: Router) { }
    // 这就是你们想要的路由守卫
    canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ) {
        console.log('【CanActivate守卫:进入当前路由】----------------------------------------', next, state);
        // 这里可以做各种路由判断的骚操作,通常我们主要是判断用户登录状态
        // 判断本地有没有token,如果token有值,表示登录成功,继续跳转
        if (localStorage.token) {
            return true;
        } else {
            //兄嘚!你都没有登录,乖乖去一下登录页面吧~
            this.router.navigate(['/login']);
            return false;
        }
    }
}

③ guard/CanActivateChild.guard.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router';
@Injectable()
export class CanActivateChildGuard implements CanActivateChild {
    constructor(private router: Router) { }
    canActivateChild(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ) {
        console.log('【CanActivateChild守卫:进入当前子路由】----------------------------------------', route, state);
        return true;//进入路由
        // return false;//中端路由
    }
}

④ guard/Resolve.guard.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { AppComponent } from '../app.component';
@Injectable()
export class ResolveGuard implements Resolve<AppComponent> {
    constructor(private router: Router) { }
    resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): any {
        console.log('【Resolve守卫:进入当前路由之后,离开之前】----------------------------------------', route, state);
    }
}

⑤ guard/CanDeactivate.guard.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, Router, RouterStateSnapshot } from '@angular/router';
import { AppComponent } from '../app.component';
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<AppComponent> {
    constructor(private router: Router) { }
    canDeactivate(
        component: AppComponent,
        currentRoute: ActivatedRouteSnapshot,
        currentState: RouterStateSnapshot,
        nextState?: RouterStateSnapshot
    ) {
        console.log('【CanDeactivate守卫:离开当前路由】----------------------------------------', currentRoute, currentState, nextState);
        return confirm('一旦离开,未保存的内容将丢失!');
    }
}

app-routing.module.ts

import { CanLoadGuard } from './guard/CanLoad.guard';
import { CanAcitivateGuard } from './guard/CanAcitivate.guard';
import { AppComponent } from './app.component';
import { ResolveGuard } from './guard/Resolve.guard';
import { CanDeactivateGuard } from './guard/CanDeactivate.guard';
import { NgModule } from '@angular/core';
import { RouterModule, Routes, Resolve, Route, UrlSegment } from '@angular/router';
import { HomeComponent } from './com/home/home.component';
import { LoginComponent } from './com/login/login.component';
import { CanActivateChildGuard } from './guard/CanActivateChild.guard';
import { ChildComponent } from './com/home/child/child.component';
const routes: Routes = [
  {
    path: '',
    component: AppComponent,
  },
  {
    path: 'home',
    component: HomeComponent,
    canLoad: [CanLoadGuard],//顺序1(刚进入路由,还未加载组件)
    canActivate: [CanAcitivateGuard],//顺序2(刚进入路由,部分组件加载)
    canActivateChild: [CanActivateChildGuard],//顺序3(刚刚进入子路由)(必须加上这个,否则会报错)
    resolve: { data: ResolveGuard },//顺序4(进入路由后)(必须加上这个,否则会报错)
    canDeactivate: [CanDeactivateGuard],//顺序5(离开路由)
    children: [
      {
        path: 'child',
        component: ChildComponent,
      }
    ]
  },
  {
    path: 'login',
    component: LoginComponent,
  },
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [
    /* 
    【CanActivate 和 CanLoad的区别】
    CanActivate:即使返回的是false,用户并没有权限访问该路由,但是相应的模块会被加载。
    CanLoad:若用户没有权限访问,相应的模块并不会被加载。这里是指对应组件的代码。
     */
    CanLoadGuard,//顺序1(刚进入路由,还未加载组件)
    CanAcitivateGuard,//顺序2(刚进入路由,部分组件加载)
    CanActivateChildGuard,//顺序3(刚刚进入子路由)(必须加上这个,否则会报错)
    ResolveGuard,//顺序4(进入路由后)(必须加上这个,否则会报错)
    CanDeactivateGuard,//顺序5(离开路由)
  ]
})
export class AppRoutingModule { }

访问localhost:4200/home打开F12查看提示:

app.component.html

<router-outlet></router-outlet>

在home里面写一个按钮点击跳转到localhost/,然后打开F12查看

app/home/home.component.ts

import { Router } from '@angular/router';
...
constructor(public router: Router) { }
...

app/home/home.component.html

<button (click)="router.navigate(['/home/child'])">跳转到child,F12去看看CanActivateChild路由守卫结果</button>
<br><br>
<button (click)="router.navigate(['/login'])">跳转到login,F12去看看CanDeactivate路由守卫结果</button>


相关文章
|
6月前
|
JavaScript 前端开发 应用服务中间件
angular引入包、路由权限配置、打包问题与nginx配置问题(简单部署)
angular引入包、路由权限配置、打包问题与nginx配置问题(简单部署)
139 0
|
3月前
|
SEO 搜索推荐 数据采集
让 JSF 应用秒变搜索引擎宠儿!揭秘 SEO 优化的神奇魔法,让你的网站脱颖而出!
【8月更文挑战第31天】随着互联网的发展,搜索引擎已成为用户获取信息的主要途径,SEO 对 Web 应用至关重要。本文介绍如何提升 JavaServer Faces(JSF)应用的 SEO 友好性,包括关键词优化、网页结构优化和外部链接建设等基础知识,并提出了使用语义化 HTML 标签、优化页面标题和描述、生成静态 HTML 页面及 URL 重写等具体策略,帮助您的网站在搜索引擎中获得更高排名。
30 0
|
3月前
|
安全 开发者
精通Angular路由管理:从基础设置到高级配置,打造复杂SPA导航系统的全方位指南
【8月更文挑战第31天】在单页应用(SPA)中,路由管理至关重要。Angular通过其强大的路由模块提供灵活高效的解决方案。本文通过代码示例详细介绍如何在Angular中设置和管理路由,包括基础路由配置、懒加载、路由保护及高级配置,帮助开发者构建高效安全的导航系统,满足复杂SPA需求。随着Angular的发展,路由管理将更加完善,值得持续关注。
31 0
|
3月前
|
JavaScript 前端开发 API
如何在 Angular 路由中使用路由解析器
如何在 Angular 路由中使用路由解析器
34 0
|
3月前
如何在 Angular 路由中使用路由守卫
如何在 Angular 路由中使用路由守卫
40 0
|
3月前
如何在 Angular 路由中使用查询参数
如何在 Angular 路由中使用查询参数
25 0
|
3月前
|
JavaScript 前端开发 测试技术
如何在 Angular 中使用懒加载路由
如何在 Angular 中使用懒加载路由
27 0
|
6月前
|
C++
【angular】启动项目和路由配置
【angular】启动项目和路由配置
45 1
|
6月前
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
|
2月前
|
缓存 JavaScript 前端开发
Angular 应用打包和部署
Angular 应用打包和部署
167 58