手把手教你使用Angular之路由與導航
一、路由
任何路由必須通過路由模組進行註冊,然後才能使用。具體程式碼如下:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; const userRoutes: Routes = [ {path: '', redirectTo: '/index', pathMatch: 'full'}, {path: 'hello/:id', component: HelloComponent} {path: 'world', component: WorldComponent, canActivate: [RouterGuard]}, { path: 'sign', component: HelloComponent, children: [ { path: 'sign-in', component: SignInComponent, data: {isAuth: false} }, ] } ]; @NgModule({ imports: [ RouterModule.forRoot(userRoutes, { useHash: true }) ], exports: [ RouterModule ], providers: [RouterGuard] }) export class WorldRouterModule { }
上例中,元件和對應的路由地址通過Route物件包裝起來,然後將Routes陣列通過RouterModule類的forRoot方法註冊,最後再將RouterModule輸出。另外,上述例子中有三個地方需要注意:
1、Route物件
Route物件作為路由註冊的最小單元,其本身因為豐富的使用場景而支援多種配置方式。常用的有如下四種
- 重定向:先通過 redirectTo 屬性指定重定向的檢視路徑,然後通過 pathMatch 屬性指定匹配規則。本例中配置的意思是,當域名後面的路徑為空時,重定向到路徑為 /index的檢視中。
- 繫結outlet:通過配置 outlet 屬性使對應檢視顯示在指定路由插座下。
- 子路由:可以通過 children 屬性配置該路徑下的子路徑以及對應檢視,也可用通過使用 loadChildren 屬性,以 loadChildren: .sign/sign-module#SignModule' 的方式配置整個模組,但該配置方式使用的是懶載入的方式。
- 路由傳參:通過使用 :引數名 的方式傳遞引數,例如 hello/:id ,可通過路徑傳遞名為id的引數。
- 路由傳值:通過使用 data 屬性來傳遞資料,然後在對應檢視中直接使用,例如 data: {isAuth: false} ,可通過路由,將 isAuth 的值 false 傳遞給對應的檢視。
2、路由守衛
上例中的第二個路由便是使用了路由守衛,路由守衛的作用是控制路由的出入口,類似於攔截器的作用,但又被細分成多種型別。路由守衛的實現方式是通過實現對應鉤子中的方法來完成路由的特定操作。部分例子如下:
import { Router, CanActivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { isNullOrUndefined } from 'util';
@Injectable()
export class RouterGuard implements CanActivate {
constructor(
private router: Router,
) {}
canActivate() {
if (isAuth) {
return true;
} else {
this.router.navigate(['/sign/sign-in']);
return false;
}
}
}
上述中的實現的是CanActivate鉤子,該鉤子是Angular用來控制路由通過與否,主要通過使用者的許可權來控制路由的流向。上例中的流程如下,若有許可權,便放行,否則便跳轉到路由地址為/sign-in的檢視中。而路由守衛的使用方法如第一個例子中,path為world的Route物件中配置了canActivate屬性,該屬性對應路由守衛中的CanActivate鉤子,即當使用CanActivate鉤子實現時,便通過canActivate屬性來配置。
3、forRoot
作為路由註冊的方法,一個應用應該只能使用一次forRoot方法。而在子模組中通常使用forChild方法。和前者不同的是,forChild僅僅只能用作註冊路由,而前者可通過可選引數config進行配置。例如上例中,通過將useHash值設為true來採用hash策略進行路由。
二、導航
這裡的導航是通過路徑跳轉到對應檢視的統稱。導航的入口通常有兩種方式,一種是通過配置連結,另一種是程式設計式。而導航的出口便是通過在頁面中使用路由插槽的方式來實現,即<router-outlet></router-outlet>,配置路由插槽的檢視會在插槽下方顯示對應的子檢視。
1、路由連結
形如 <a routerLink="/world"></a> ,但具體的使用方式十分豐富,常用的使用如下:
- 路徑引數: <a routerLink="/hello/Tylili"></a> 或者 <a [routerLink]="['/hello', 'Tylili']"></a> ,該連結對應上例中的 {path: 'hello/:id', component: HelloComponent} ,將tylili作為引數id的值傳送出去。
- 路由傳參: <a [routerLink]="['/world', 'Tylili']" [queryParams]="{name:'Tylili'}"></a>,該連結將傳送一個名為name,值為Tylili的引數。
2、程式設計式導航
程式設計式導航是指通過 Router 物件進行導航,常用使用方法如下:
- 路徑傳參:this.router. navigateByUrl('/hello/Tylili') 或者 this.router.navigate(['/hello', 'Tylili']),意思同路由連結中的路徑傳參。
- 路由傳參:this.router.navigate(['/hello'], { queryParams: { name: 'Tylili' } }) ,意思同路由連結中的路由傳參。
3、獲取引數
通過 ActivatedRoute 物件,我們可以獲取路徑引數,也可以獲取路由引數。
形如 this.route.snapshot.params.name 或者 this.route.snapshot.paramMap.get('name'),該方式用來獲取路徑引數。
形如 this.route.snapshot.queryParams.name ,該方式用來獲取路由引數。
4、路由插槽
一個檢視中可以有多個路由插槽,但只能有一個住插槽,其餘插槽均需使用 name 命名,例如:
<router-outlet></router-outlet>
<router-outlet name="one"></router-outlet>
<router-outlet name="two"></router-outlet>