☕ NEW! 完成新手任務即可參加抽獎!LINE 星巴克禮券等你拿,名額有限!        🎉 推廣活動:邀請好友註冊 DevLearn,累積推薦抽 LINE 星巴克禮券! 活動詳情 →        🔥 活動期間 2026/4/1 - 5/31 |已有 0 人參加       
angular 中級

🧭 Angular Router:導航與路由管理

📌 路由模組設定

Angular Router 讓你在單一頁面中切換不同的「視圖」,實現 SPA(Single Page Application)。

// app.routes.ts
import { Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ProductListComponent } from './products/product-list.component';
import { ProductDetailComponent } from './products/product-detail.component';
import { NotFoundComponent } from './not-found/not-found.component';

export const routes: Routes = [
  { path: '', component: HomeComponent },                    // 首頁
  { path: 'about', component: AboutComponent },              // /about
  { path: 'products', component: ProductListComponent },     // /products
  { path: 'products/:id', component: ProductDetailComponent }, // /products/123
  { path: '**', component: NotFoundComponent }               // 404 萬用路由(放最後)
];
// app.config.ts — Standalone 模式設定
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes)]
};
<!-- app.component.html -->
<nav>
  <!-- routerLink 取代傳統的 <a href>,不會重新載入頁面 -->
  <a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">首頁</a>
  <a routerLink="/about" routerLinkActive="active">關於</a>
  <a routerLink="/products" routerLinkActive="active">產品</a>
</nav>

<!-- router-outlet 是路由的「出口」,符合的元件會顯示在這裡 -->
<router-outlet></router-outlet>

<footer>版權所有 &copy; 2024</footer>

💡 routerLinkActive="active" 會在目前路由符合時自動加上 active CSS 類別。

📌 路由參數與查詢參數

路由參數(Route Parameters)

// product-detail.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-product-detail',
  template: `
    <h2>產品詳情</h2>
    <p>產品 ID:{{ productId }}</p>
  `
})
export class ProductDetailComponent implements OnInit {
  productId = '';

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    // 方法 1:快照(適合不會變的參數)
    this.productId = this.route.snapshot.paramMap.get('id') ?? '';

    // 方法 2:Observable(適合同一元件中參數會改變的情況)
    this.route.paramMap.subscribe(params => {
      this.productId = params.get('id') ?? '';
      // 重新載入資料...
    });
  }
}

查詢參數(Query Parameters)

<!-- 傳遞查詢參數 /products?category=phone&sort=price -->
<a routerLink="/products" [queryParams]="{category: 'phone', sort: 'price'}">
  手機(按價格排序)
</a>
// 讀取查詢參數
this.route.queryParamMap.subscribe(params => {
  const category = params.get('category');  // 'phone'
  const sort = params.get('sort');          // 'price'
});

📌 子路由(Child Routes)

// 路由設定
export const routes: Routes = [
  {
    path: 'admin',
    component: AdminLayoutComponent,
    children: [
      { path: '', component: AdminDashboardComponent },       // /admin
      { path: 'users', component: AdminUsersComponent },      // /admin/users
      { path: 'settings', component: AdminSettingsComponent } // /admin/settings
    ]
  }
];
<!-- admin-layout.component.html -->
<div class="admin-layout">
  <aside>
    <a routerLink="/admin">儀表板</a>
    <a routerLink="/admin/users">使用者管理</a>
    <a routerLink="/admin/settings">系統設定</a>
  </aside>
  <main>
    <router-outlet></router-outlet>  <!-- 子路由的出口 -->
  </main>
</div>

📌 路由守衛(Guards)

// auth.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';

// CanActivate — 進入路由前檢查(最常用)
export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true;  // 允許進入
  }

  // 未登入 → 導向登入頁,並記住原本要去的頁面
  return router.createUrlTree(['/login'], {
    queryParams: { returnUrl: state.url }
  });
};

// 在路由設定中使用守衛
export const routes: Routes = [
  { path: 'admin', component: AdminComponent, canActivate: [authGuard] },
  { path: 'login', component: LoginComponent }
];

📌 懶載入模組(Lazy Loading)

// 懶載入 — 只有進入該路由時才下載對應的程式碼
export const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () => import('./admin/admin.component')
      .then(m => m.AdminComponent)
  },
  {
    path: 'reports',
    loadChildren: () => import('./reports/reports.routes')
      .then(m => m.REPORT_ROUTES)  // 載入整個子路由模組
  }
];

💡 效能優化:懶載入讓首頁只下載必要的程式碼,其他頁面的程式碼按需載入。 這對大型應用特別重要——使用者不需要一次下載所有程式碼。

📌 程式化導航

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

@Component({ /* ... */ })
export class MyComponent {
  constructor(private router: Router) { }

  goToProduct(id: number) {
    // 程式碼中觸發導航
    this.router.navigate(['/products', id]);
  }

  goToSearch(term: string) {
    this.router.navigate(['/search'], {
      queryParams: { q: term }
    });
  }
}

📌 小結

  • Routes 陣列定義路徑和元件的對應關係
  • <router-outlet> 是路由元件的顯示區域
  • 路由參數 :id 用於動態路徑,查詢參數用於篩選
  • 子路由實現嵌套的頁面佈局
  • 路由守衛控制存取權限(如登入驗證)
  • 懶載入大幅提升首頁載入速度

💡 大家的想法 · 0

載入中...
💬 即時聊天室 🟢 0 人在線
😀 😎 🤓 💻 🎮 🎸 🔥
➕ 新問題
📋 我的工單
💬 LINE 社群
🔒
需要註冊才能使用此功能
註冊帳號即可解鎖測驗、遊戲、簽到、筆記下載等所有功能,完全免費!
免費註冊