随着互联网的不断发展,SPA(Single Page Application)应用越来越受欢迎。SPA应用的前端开发离不开路由配置,Angular 6是一款非常优秀的前端框架,它提供了路由配置工具,让我们可以轻松地构建SPA应用。本文将介绍如何使用Angular 6开发SPA应用时,进行路由配置及路由配置的一些坑点解析,以及一些实用的技巧。
一、路由配置
1.1 路由的基本概念
路由是一个Web 应用中的重要部分,它用来控制用户请求的URL,根据URL的不同,我们可以展现出不同的页面、内容或功能。Angular应用的路由是由 RouterModule 提供的。
Angular路由需要配置一个或多个路由,每个路由又是由路由器定义和解析的一组信息,它可以包括路径、组件和其他参数等。在 Angular 应用中,路由的配置是在 AppModule 中进行的,同时也需要引入 RouterModule 模块。
1.2 路由的基本配置
下面是一个基本的路由配置示例:
// javascriptcn.com 代码示例 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home.component'; import { AboutComponent } from './about.component'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRoutingModule { }
在代码中,我们定义了两个路由:HomeComponent 和 AboutComponent。路由的对象是由 path 和 component 而组成的,path 定义了路由的路径,component 定义了路由需要加载的组件。
其中,path:'' 是默认路由,在应用启动时会自动进行加载。如果地址路径匹配不到任何路由,则访问默认路由。
1.3 路由传参
路由传参是在组件之间传递参数的一种方式。在 Angular 6 中,可以通过如下方式来实现路由传参:
通过URL传递参数
const routes: Routes = [ { path: 'product/:id', component: ProductComponent } ];
在这个例子中,路由地址为 /product/:id,其中 :id 表示要传递的参数,传递的值在URL中传递,例如:/product/1001。
通过路由配置传递参数
const routes: Routes = [ { path: 'product', component: ProductComponent, data: { productId: 1001 } } ];
在这个例子中,数据参数可以在 ActivatedRoute service 中取到
1.4 路由的重定向
重定向是一种常见的路由配置技巧,它可以使路由地址被替换为另一个地址,例如:
const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent } ];
在这个例子中,匹配空路径时重定向到 /home。
二、路由配置及坑点解析
2.1 坑点1:模块化加载路由模块
在开发SPA应用时,通常会分成多个路由模块,每个路由模块都负责自己的路由配置。这时候,需要注意 Angular 的模块化加载机制。在 Angular 中,模块是懒加载的,不会一次性将所有的代码加载到浏览器中,而是按照需要进行加载。
因此,在使用路由模块的时候,需要注意在父级模块中声明其路由配置,同时在子级路由模块中进行路由配置的定义。例如:
// javascriptcn.com 代码示例 // app-routing.module.ts const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule' } // 声明了应用的默认路由,并将 /lazy 路径委托给了 LazyModule ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } // lazy.module.ts const routes: Routes = [ { path: '', component: LazyComponent } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class LazyModule { }
在以上的例子中,通过调用 RouterModule.forChild 来定义LazyModule 模块的路由配置,并将其导出以供使用。
2.2 坑点2:路由默认值
在实际开发中,路由的默认值非常重要。在 Angular 中,我们可以通过配置默认路由来实现这一点。
const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: '**', component: NotFoundComponent } ];
在这个例子中,我们通过使用通配符路由来定义 NotFoundComponent 组件,同时将重定向配置到了 HomeComponent 上。
2.3 坑点3:路由守卫
路由守卫是用来保护路由的,通过它可以有效地控制路由的访问。在 Angular 中,路由守卫通常包括以下几种类型:
路由前置守卫
当试图导航到某个路由时,路由前置守卫会检查当前用户是否有权限去访问该路由。例如,需要登录后才能访问会员中心。
路由后置守卫
当试图离开某个路由时,路由后置守卫会检查当前用户是否已经完成所需的操作。例如,在用户提交表单之前需要确认。
路由解析守卫
路由解析守卫用来检查当前请求的路由是否能被解析。例如,检查存放产品ID的URL参数是否合法。
下面是一个路由守卫的示例:
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable() export class AuthGuard implements CanActivate { constructor( private authService: AuthService, private router: Router ) {} canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { if (this.authService.isLoggedIn()) { return true; } this.router.navigate(['/login']); return false; // 取消路由导航 } }
在这个例子中,AuthGuard 通过 canActivate 方法返回一个布尔值,如果为 true 则导航可以继续,如果为 false 则要取消导航,并跳转到 login 路由。
三、使用 Angular 6 开发 SPA 应用的实用技巧
3.1 路由跳转
在 Angular 6 中,路由跳转有两种方式,分别为 imperative navigation(命令式导航)和 declarative navigation(声明式导航)。其中,命令式导航使用 Router 服务,而声明式导航则通过 routerLink 指令来实现。
3.1.1 命令式导航
在命令式导航中,我们可以使用 Router 服务来实现路由跳转。例如:
// javascriptcn.com 代码示例 import { Component } from '@angular/core'; import { Router } from '@angular/router'; @Component({ template: ` <button (click)="gotoAbout()">About</button> ` }) export class HomeComponent { constructor(private router: Router) {} gotoAbout(): void { this.router.navigate(['/about']); } }
在这个例子中,我们通过 Router 服务来实现路由跳转。其中,router.navigate 方法接收一个包含要跳转路由配置和参数信息的数组。
3.1.2 声明式导航
在声明式导航中,我们可以使用 routerLink 指令来实现路由跳转。例如:
import { Component } from '@angular/core'; @Component({ template: ` <a routerLink="/about">About</a> ` }) export class HomeComponent {}
在这个例子中,我们使用 routerLink 指令来实现路由跳转。其中,routerLink 指令接收一个包含目标路由地址的字符串。
3.2 守卫跳转
守卫跳转是指在路由跳转之前执行守卫,并根据守卫返回的结果来决定是否执行路由跳转。在实现守卫跳转前,需要了解 Angular 中的路由生命周期。
先来看一下路由生命周期的流程:
- NavigationStart(路由开始导航,可以取消导航)。
- RouteConfigLoadStart(路由配置开始加载)
- RouteConfigLoadEnd(路由配置加载完成)
- RoutesRecognized(路由被识别)
- GuardsCheckStart(路由守卫检查开始)
- ChildActivationStart(开始子路由激活)
- ActivationStart(路由激活开始)
- GuardsCheckEnd(路由守卫检查结束)
- ResolveStart(路由数据被解析)
- ResolveEnd(路由数据被解析完毕)
- ActivationEnd(路由激活结束)
- ChildActivationEnd(子路由激活结束)
- NavigationEnd(路由导航结束),也就是页面完成导航之后触发。
- NavigationCancel(路由导航取消)
- NavigationError(路由导航出错)
在生命周期的过程中,GuardsCheckStart(路由守卫检查开始)和 GuardsCheckEnd(路由守卫检查结束)生命周期是在路由跳转中进行路由守卫。因此,我们可以通过实现 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(): Promise<boolean> { return this.authService.isLoggedIn().then(result => { if (result) { return true; } else { this.router.navigate(['/login']); return false; } }); } }
在这个例子中,我们通过实现 CanActivate 接口来实现路由守卫,并在守卫检查中判断当前用户是否已经登录,如果没有登录,则跳转到 login 路由。
本文总结
本文介绍了如何使用 Angular 6 开发SPA应用时进行路由配置并解析路由配置的一些坑点。同时,还介绍了一些实用的技巧,例如路由跳转和守卫跳转。通过本文的学习,相信大家已经可以轻松地使用 Angular 6 进行SPA应用开发了!
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6534847b7d4982a6eb92b7bc