路由守卫是 Angular 中的一个重要特性,它可以帮助我们在导航到某个路由之前或之后执行一些逻辑。通过使用路由守卫,我们可以控制用户是否可以访问某个路由,以及在用户访问某个路由时执行一些操作。
在本文中,我们将介绍 Angular 中的路由守卫,并提供一些示例代码来演示如何使用它。
路由守卫的种类
在 Angular 中,路由守卫分为以下几种类型:
- CanActivate:用于控制用户是否可以访问某个路由。
- CanActivateChild:用于控制用户是否可以访问某个路由的子路由。
- CanDeactivate:用于控制用户是否可以离开当前路由。
- Resolve:用于在导航到某个路由之前解析数据。
使用 CanActivate 守卫
CanActivate 守卫用于控制用户是否可以访问某个路由。如果用户没有权限访问该路由,则可以使用 CanActivate 守卫将用户重定向到其他页面。
在使用 CanActivate 守卫时,我们需要定义一个实现了 CanActivate 接口的类。该类需要实现 canActivate 方法,该方法会在用户访问某个路由之前被调用。如果该方法返回 true,则用户可以访问该路由,否则用户将被重定向到其他页面。
下面是一个示例代码,演示如何使用 CanActivate 守卫:
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { CanActivate, Router } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable() export class AuthGuard implements CanActivate { constructor(private authService: AuthService, private router: Router) {} canActivate(): boolean { if (!this.authService.isAuthenticated()) { this.router.navigate(['login']); return false; } return true; } }
在上面的代码中,我们定义了一个名为 AuthGuard 的类,它实现了 CanActivate 接口。在 canActivate 方法中,我们首先调用了 AuthService 的 isAuthenticated 方法,该方法用于检查用户是否已经认证。如果用户没有认证,则我们将用户重定向到登录页面,并返回 false。否则,我们返回 true,允许用户访问该路由。
要在路由中使用 CanActivate 守卫,我们需要在路由定义中添加 canActivate 属性,该属性的值为一个数组,包含实现了 CanActivate 接口的类。
下面是一个示例代码,演示如何在路由中使用 CanActivate 守卫:
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; import { AuthGuard } from './auth.guard'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent, canActivate: [AuthGuard] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
在上面的代码中,我们定义了两个路由:一个用于显示主页,另一个用于显示关于页面。在关于页面的路由定义中,我们添加了一个 canActivate 属性,该属性的值为一个包含 AuthGuard 类的数组。这意味着只有当用户已经认证时,才能访问关于页面。
使用 CanActivateChild 守卫
CanActivateChild 守卫用于控制用户是否可以访问某个路由的子路由。如果用户没有权限访问该路由的子路由,则可以使用 CanActivateChild 守卫将用户重定向到其他页面。
在使用 CanActivateChild 守卫时,我们需要定义一个实现了 CanActivateChild 接口的类。该类需要实现 canActivateChild 方法,该方法会在用户访问某个路由的子路由之前被调用。如果该方法返回 true,则用户可以访问该路由的子路由,否则用户将被重定向到其他页面。
下面是一个示例代码,演示如何使用 CanActivateChild 守卫:
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { CanActivateChild, Router } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable() export class AuthChildGuard implements CanActivateChild { constructor(private authService: AuthService, private router: Router) {} canActivateChild(): boolean { if (!this.authService.isAuthenticated()) { this.router.navigate(['login']); return false; } return true; } }
在上面的代码中,我们定义了一个名为 AuthChildGuard 的类,它实现了 CanActivateChild 接口。在 canActivateChild 方法中,我们首先调用了 AuthService 的 isAuthenticated 方法,该方法用于检查用户是否已经认证。如果用户没有认证,则我们将用户重定向到登录页面,并返回 false。否则,我们返回 true,允许用户访问该路由的子路由。
要在路由中使用 CanActivateChild 守卫,我们需要在路由定义中添加 canActivateChild 属性,该属性的值为一个数组,包含实现了 CanActivateChild 接口的类。
下面是一个示例代码,演示如何在路由中使用 CanActivateChild 守卫:
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; import { AuthChildGuard } from './auth-child.guard'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent, canActivateChild: [AuthChildGuard] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
在上面的代码中,我们定义了两个路由:一个用于显示主页,另一个用于显示关于页面。在关于页面的路由定义中,我们添加了一个 canActivateChild 属性,该属性的值为一个包含 AuthChildGuard 类的数组。这意味着只有当用户已经认证时,才能访问关于页面的子路由。
使用 CanDeactivate 守卫
CanDeactivate 守卫用于控制用户是否可以离开当前路由。如果用户在离开当前路由之前需要执行一些操作,例如保存表单数据,可以使用 CanDeactivate 守卫来提示用户是否要保存数据。
在使用 CanDeactivate 守卫时,我们需要定义一个实现了 CanDeactivate 接口的类。该类需要实现 canDeactivate 方法,该方法会在用户离开当前路由之前被调用。如果该方法返回 true,则用户可以离开当前路由,否则用户将被提示是否要保存数据。
下面是一个示例代码,演示如何使用 CanDeactivate 守卫:
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { CanDeactivate } from '@angular/router'; import { Observable } from 'rxjs'; import { FormComponent } from './form.component'; @Injectable() export class FormGuard implements CanDeactivate<FormComponent> { canDeactivate(component: FormComponent): Observable<boolean> | boolean { if (component.isDirty()) { return confirm('Are you sure you want to discard your changes?'); } return true; } }
在上面的代码中,我们定义了一个名为 FormGuard 的类,它实现了 CanDeactivate 接口。在 canDeactivate 方法中,我们首先调用了 FormComponent 的 isDirty 方法,该方法用于检查表单数据是否已经被修改。如果表单数据已经被修改,则我们将提示用户是否要保存数据,并返回一个 Observable 对象。如果表单数据未被修改,则我们返回 true,允许用户离开当前路由。
要在路由中使用 CanDeactivate 守卫,我们需要在路由定义中添加 canDeactivate 属性,该属性的值为一个实现了 CanDeactivate 接口的类。
下面是一个示例代码,演示如何在路由中使用 CanDeactivate 守卫:
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { FormComponent } from './form/form.component'; import { FormGuard } from './form.guard'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'form', component: FormComponent, canDeactivate: [FormGuard] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
在上面的代码中,我们定义了两个路由:一个用于显示主页,另一个用于显示表单页面。在表单页面的路由定义中,我们添加了一个 canDeactivate 属性,该属性的值为一个包含 FormGuard 类的数组。这意味着只有当表单数据未被修改时,才能离开当前路由。
使用 Resolve 守卫
Resolve 守卫用于在导航到某个路由之前解析数据。如果我们需要在用户访问某个路由之前从服务器获取数据,可以使用 Resolve 守卫来解析数据。
在使用 Resolve 守卫时,我们需要定义一个实现了 Resolve 接口的类。该类需要实现 resolve 方法,该方法会在用户访问某个路由之前被调用。在 resolve 方法中,我们可以从服务器获取数据,并将数据返回给路由。
下面是一个示例代码,演示如何使用 Resolve 守卫:
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { Resolve } from '@angular/router'; import { Observable } from 'rxjs'; import { DataService } from './data.service'; @Injectable() export class DataResolver implements Resolve<any> { constructor(private dataService: DataService) {} resolve(): Observable<any> { return this.dataService.getData(); } }
在上面的代码中,我们定义了一个名为 DataResolver 的类,它实现了 Resolve 接口。在 resolve 方法中,我们调用了 DataService 的 getData 方法,该方法用于从服务器获取数据,并返回一个 Observable 对象。
要在路由中使用 Resolve 守卫,我们需要在路由定义中添加 resolve 属性,该属性的值为一个实现了 Resolve 接口的类。
下面是一个示例代码,演示如何在路由中使用 Resolve 守卫:
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { DataComponent } from './data/data.component'; import { DataResolver } from './data.resolver'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'data', component: DataComponent, resolve: { data: DataResolver } } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
在上面的代码中,我们定义了两个路由:一个用于显示主页,另一个用于显示数据页面。在数据页面的路由定义中,我们添加了一个 resolve 属性,该属性的值为一个包含 DataResolver 类的对象。这意味着在用户访问数据页面之前,我们将从服务器获取数据,并将数据传递给 DataComponent 组件。
总结
在本文中,我们介绍了 Angular 中的路由守卫,并提供了一些示例代码来演示如何使用它。通过使用路由守卫,我们可以控制用户是否可以访问某个路由,以及在用户访问某个路由时执行一些操作。希望本文能够对你有所帮助,让你更好地掌握 Angular 中的路由守卫。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65561928d2f5e1655d0947eb