Angular Router路由的使用

設定路由

一前置作業新增頁面

新增Home與fetchData 頁面
新增Home頁面
1
2
3
// 新增元件指令
ng g c 頁面或是功能
ng g c Home
產生了home 資料夾內有以下檔案
1
2
3
4
home.component.html
home.component.scss
home.component.spec.ts
home.component.ts
新增user 頁面
1
ng g c User
產生了ng g c User 資料夾內有以下檔案
1
2
3
4
user.component.html
user.component.scss
user.component.spec.ts
user.component.ts
新增PageNotFound 頁面
1
ng g c PageNotFound
產生了page-not-found 資料夾內有以下檔案
1
2
3
4
page-not-found.component.html
page-not-found.component.scss
page-not-found.component.spec.ts
page-not-found.component.ts
二 在 app.routes.ts檔案設定
  • 引入Home,Users,User,PageNotFound元件,解構寫法必須加名稱Component 大駝峰式寫法
  • export const routes: Routes = [path: '路徑', component: 頁面元件]
  • 首頁 { path: "", redirectTo:'home',pathMatch:'full' },
  • 404頁 { path: '**', component: PageNotFoundComponent }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Routes } from '@angular/router';
//引入,解構寫法必須加名稱Component 大駝峰式寫法
import { HomeComponent } from './home/home.component';
import { UsersComponent } from './users/users.component';
import { UserComponent } from './user/user.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

export const routes: Routes = [
{ path: "", redirectTo:'home',pathMatch:'full' },
{ path: "home", component:HomeComponent },
{ path: "users", component: UsersComponent},
{ path: "user/:userId", component: UserComponent},
{ path: '**', component: PageNotFoundComponent }, // 404頁面
];

配置應用程式 在app.config.ts檔案中新增以下設定:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

+ import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';

export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
+ provideRouter(routes),
provideClientHydration(),
provideAnimationsAsync()
]
};

this.router.navigate([‘users’]); 切換至頁面

  • 引入Router
  • constructor( private router: Router, ) { ... }
  • this.router.navigate([path網址])
1
2
3
4
5
6
7
8
9
10
11
12
import {  Router } from '@angular/router';

constructor(
private router: Router,
) {
...
}

viewProduct( item: any): void {
console.log(item)
this.router.navigate(["/index/product/"+item._id]);
}
### 元件的引入(Navba主選單的切換) 到components新增
1
2
// ng g c 頁面或是功能
ng g c Navbar
產生了navbar 資料夾內有以下檔案
1
2
3
4
navbar.component.html
navbar.component.scss
navbar.component.spec.ts
navbar.component.ts
利用 routerLink 指令實作頁面切換 navbar.component.html檔案內新增
  • routerLink是routes內的path
  • routerActive="active"
1
2
3
4
5
6
7
8
9
10
11
<nav class="nav">
<ul>
<li>
<a routerLink="/" routerActive="active" class="cursor-pointer">Home</a>
</li>
<li>
<a routerLink="fetch-data" routerActive="active" class="cursor-pointer">FetchData</a>
</li>
</ul>
</nav>

navbar.component.ts
引入RouterLink
import { RouterLink} from '@angular/router';
@Component({
imports: [
RouterLink
],
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Component } from '@angular/core';
+ import { RouterLink } from '@angular/router';
@Component({
selector: 'app-navbar',
standalone: true,
imports: [
+ RouterLink
],
templateUrl: './navbar.component.html',
styleUrl: './navbar.component.scss'
})
export class NavbarComponent {

}

在首頁載入

在 app.component.ts
引入NavbarComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
+ import { NavbarComponent } from './components/navbar/navbar.component';
import { environment } from '../environments/environment';

@Component({
selector: 'app-root',
imports: [
RouterOutlet,
+ NavbarComponent,
],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
title = environment.production ? 'Production' : '開發中';
}

嵌套路由

1
<router-outlet></router-outlet>

在 app.component.html 會使用 , 元件來定義頁面所需要顯示的位置

1
2
3
4
5
<app-navbar></app-navbar>
<main class="main">
<router-outlet />
</main>

router 案例github

404 頁面

如果要顯示自訂 404 頁面,請設定通配符路由,並將元件屬性設定為PageNotFoundComponent

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Routes } from '@angular/router';
//引入,解構寫法必須加名稱Component 大駝峰式寫法
import { HomeComponent } from './home/home.component';
import { UsersComponent } from './users/users.component';
import { UserComponent } from './user/user.component';
+ import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

export const routes: Routes = [
{ path: "", component: HomeComponent },
{ path: "users", component: UsersComponent},
{ path: "user/:userId", component: UserComponent},
+ { path: '**', component: PageNotFoundComponent }, // 404頁面
];

router 初次設定

動態 Router

以UserComponent(user資料夾user.component.ts) 為例
  • 載入@angular/core 的inject 載入@angular/router 的 ActivatedRoute,
  • private activeRouter = inject(ActivatedRoute);
  • this.activeRouter.snapshot.paramMap.get('userId')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+  import { Component, OnInit, inject } from '@angular/core';
+ import { CommonModule } from '@angular/common';
+ import { ActivatedRoute } from '@angular/router';

@Component({
selector: 'app-user',
imports: [
+ CommonModule,// Angular 17以後必須引入
],
templateUrl: './user.component.html',
styleUrl: './user.component.scss'
})
+ export class UserComponent implements OnInit{
+ private activeRouter = inject(ActivatedRoute);
+ ngOnInit(): void {
+ this.getDetailID();
+ }

+ getDetailID(): void {
+ const userId = this.activeRouter.snapshot.paramMap.get('userId');
+ console.log('userId', userId);
+ }
}

模組化且延遲載入,提升更好的使用者體驗

Angular 19 App with Lazy Loading
隨著專案的擴大,路由設定會越來越大,元件也會越來越多

  • loadComponent:() => import('檔案位置').then((m)=> m.HomeComponent)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

import { Routes } from '@angular/router';

import { UserComponent } from './user/user.component';

export const routes: Routes = [
{ path: "", redirectTo: 'home', pathMatch: 'full' },
{
path: "home",
loadComponent:() => import('./home/home.component').then((m)=> m.HomeComponent)
},
{
path: "users",
loadComponent:() =>import('./users/users.component').then((m)=>m.UsersComponent)
},
{
path: "user/:userId",
component: UserComponent
},
{
path: "login",
loadComponent:() =>import('./login/login.component').then((m)=>m.LoginComponent)
},
{
path: "test_login",
loadComponent:()=>import('./test-login/test-login.component').then((m)=>m.TestLoginComponent)
},
{
path: "admin",
loadComponent:() =>import('./admin/index-admin/index-admin.component').then((m)=>m.IndexAdminComponent) ,
children: [
{
path: "admin_home",
loadComponent:()=>import('./admin/look/look.component').then((m)=>m.LookComponent)
},
{ path: '', redirectTo: 'admin_home', pathMatch: 'full' },
]
},
{
// 404頁面
path: '**',
loadComponent: () => import('./page-not-found/page-not-found.component').then((m) => m.PageNotFoundComponent)
},
];