iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0
Modern Web

Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站系列 第 14

Day 14 Angular 巢狀路由與 Lazy Loading – 作品詳情子頁面

  • 分享至 

  • xImage
  •  

今日目標

  • 認識 巢狀路由 (child routes)<router-outlet> 的嵌套使用
  • 在「作品詳情」頁建立 Info / Gallery 子頁
  • 學會設定 Lazy Loading 模組,僅在需要時才載入

基礎概念

巢狀路由

  • 路由表可以有 children,代表子路由。
  • 父元件放一個 <router-outlet>,子路由的內容就會渲染在裡面。

例如:

{ path: 'projects/:id', component: ProjectDetailComponent, children: [
  { path: 'info', component: ProjectInfoComponent },
  { path: 'gallery', component: ProjectGalleryComponent }
]}

Lazy Loading

  • 預設情況下,所有元件/模組都會在一開始載入。
  • Lazy Loading 可以讓某些模組延後載入,只在使用者真的進到那個路由時才抓。
  • 在 Angular 14+,常用 loadChildren 搭配 import()

實作:巢狀路由

1) 新增子元件

建立兩個子元件:

ng g c components/project-info
ng g c components/project-gallery


2) 修改路由設定

app.module.tsroutes 調整:

const routes: Routes = [
  { path: '', component: ProjectsComponent },
  {
    path: 'projects/:id',
    component: ProjectDetailComponent,
    children: [
      { path: 'info', component: ProjectInfoComponent },
      { path: 'gallery', component: ProjectGalleryComponent },
      { path: '', redirectTo: 'info', pathMatch: 'full' } // 預設顯示 info
    ]
  },
  { path: '**', redirectTo: '' }
];


3) 修改 ProjectDetailComponent

project-detail.component.html 增加子導覽與嵌套的 <router-outlet>

<div class="container section" *ngIf="project">
  <h2>{{ project.title }}</h2>
  <p class="muted">{{ project.tech }}</p>

  <nav class="sub-nav">
    <a [routerLink]="['info']" routerLinkActive="active">資訊</a>
    <a [routerLink]="['gallery']" routerLinkActive="active">圖片</a>
  </nav>

  <router-outlet></router-outlet>

  <br />
  <a routerLink="/" class="btn btn-outline">返回首頁</a>
</div>


4) 在子元件顯示內容

project-info.component.html

<section>
  <h3>專案介紹</h3>
  <p>這裡可以放更多專案的背景描述、技術挑戰、心得。</p>
</section>

project-gallery.component.html

<section>
  <h3>專案截圖</h3>
  <img src="assets/demo1.png" alt="專案截圖1" width="400">
  <img src="assets/demo2.png" alt="專案截圖2" width="400">
</section>


實作:Lazy Loading 模組

假設我們想把「Projects 區域」獨立成一個模組,只在需要時才載入。

1) 建立模組

ng g module projects --route projects --module app.module

Angular CLI 會自動產生 projects.module.ts 與路由設定。

2) 調整檔案

  • ProjectsComponentProjectDetailComponentProjectInfoComponentProjectGalleryComponent 移到 projects/ 模組裡。
  • projects-routing.module.ts 會包含:
const routes: Routes = [
  { path: '', component: ProjectsComponent },
  { path: ':id', component: ProjectDetailComponent, children: [
    { path: 'info', component: ProjectInfoComponent },
    { path: 'gallery', component: ProjectGalleryComponent }
  ]}
];

3) 主路由改成 Lazy Loading

app.module.ts 的路由:

const routes: Routes = [
  { path: '', redirectTo: 'projects', pathMatch: 'full' },
  { path: 'projects', loadChildren: () => import('./projects/projects.module').then(m => m.ProjectsModule) },
  { path: '**', redirectTo: 'projects' }
];


成果

  • /projects/0/info → 顯示專案資訊
  • /projects/0/gallery → 顯示專案圖片
  • Projects 區域被拆成獨立模組,只有在訪問 /projects 時才會載入,提高效能

小心踩雷

  1. 子路由忘了放 <router-outlet>
    • ❌ ProjectDetail 沒 router-outlet → 子頁面不會顯示
    • ✅ 父元件必須放一個 <router-outlet>
  2. 相對路徑錯誤
    • [routerLink]="'/info'" → 跑到根路徑
    • [routerLink]="['info']" → 相對於父路由
  3. Lazy Loading 模組沒匯出元件
    • 元件要在對應的模組 declarations,否則會報錯

下一步(Day 15 預告)

Angular 階段最後一天,我們要:

  • 串接 HttpClient,模擬從 API 讀取 Projects 資料
  • 加上 Loading 狀態錯誤處理
  • 正式完成「Angular 版履歷網站」 🎉

上一篇
Day 13 Angular Routing – 作品集加上「詳情頁」
下一篇
Day 15 Angular Pipe 與 Directive – 讓模板更聰明
系列文
Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言