iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0

前言

路由是 Angular 裡很重要的部分,以前的網頁技術 MPA 透過改變 url 對 server 發起頁面需求來達到換頁的效果,而所謂的 SPA 單頁應用程式則是透過 Router 技術進行換頁,好處是不需要等待 server 回應,速度上會快很多,但是也有 SEO ( 搜尋引擎最佳化) 的問題


前端路由的定義

  • 點擊連結後,會連到對應的頁面。
  • 在網址列中輸入 URL 後,會導頁到對應的頁面。
  • 點擊瀏覽器的上下頁按鈕後,會根據瀏覽器的歷史紀錄導頁。

Angular 路由模組的設定方法

根模組引入路由模組

ng new 的時候新專案自己會產生 app-routing.module.ts,如果一開始沒有選擇加入路由模組,則需要手動加入根模組,
src\app\app.module.ts

...

// 引入路由模組
import { AppRoutingModule } from './app-routing.module';

// Home Components
import { HomeComponent } from './home/home.component';
import { TenantComponent } from './tenant/tenant.component';
import { AboutComponent } from './about/about.component';
import { LandComponent } from './land/land.component';
import { PublicityComponent } from './publicity/publicity.component';

// Sibling Component
import { LandRecordComponent } from './land-record/land-record.component';

...

@NgModule({
    declarations: [AppComponent, HomeComponent, TenantComponent, AboutComponent, LandComponent, LandRecordComponent, PublicityComponent],
    imports: [
        ...

        AppRoutingModule,

        ...

        ...NEBULAR_ROOT,
        ...NEBULAR_ALL,
    ],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

路由模組設定

src\app\app-routing.module.ts

// Home Components
import { HomeComponent } from './home/home.component';
import { TenantComponent } from './tenant/tenant.component';
import { AboutComponent } from './about/about.component';
import { LandComponent } from './land/land.component';
import { PublicityComponent } from './publicity/publicity.component';

// 路由設定
const routes: Routes = [
    {
        path: 'home', // 首頁元件路由
        component: HomeComponent,
        children: [
            {
                path: 'tenant', // 首頁元件的子路由 - home/tenant
                component: TenantComponent,
            },
            {
                path: 'about', // 首頁元件的子路由 - home/about
                component: AboutComponent,
            },
            {
                path: 'land', // 首頁元件的子路由 - home/land
                component: LandComponent,
            },
            {
                path: 'publicity', // 首頁元件的子路由 - home/publicity
                component: PublicityComponent,
            },
        ],
    },
    // 沒有路由路徑時自動導轉 home/about
    { path: '', redirectTo: 'home/about', pathMatch: 'full' },

    // 對應不到路由路徑時自動導轉 home/about
    { path: '**', redirectTo: 'home/about' },
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
})
export class AppRoutingModule {}

根元件路由設定 src\app\app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    template: `<router-outlet></router-outlet>`    // 路由模組會在此處代換頁面
})
export class AppComponent {}

Angular 路由使用方式

頁面中顯示連結的方式

src\app\about\about.component.html

<a [routerLink]="['/home/about']">公司簡介</a>
<a [routerLink]="['/home/tenant']">租戶管理</a>
<a [routerLink]="['/home/land']">土地管理</a>
<a [routerLink]="['/home/publicity']">廣告宣傳</a>

about.component.html 點擊連結就會顯示對應元件的內容。

程式中路由使用方式

使用 Router Service 在程式中使用 this.router.navigate 服務在程式內操作路由行為。
src\app\home\home.component.ts

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

...

constructor(private router: Router) {}

...

this.router.navigate(['/home/about']);
this.router.navigate(['/home/tenant']);
this.router.navigate(['/home/land']);
this.router.navigate(['/home/publicity']);

navigate說明文件 NavigationExtras

使用 Nebular NbMenuItem 元件的方式

src\app\home\home.menuitem.ts

export const NbMenuItems = [
    {
        key: 'ABOUT.TITLE', // 對應 i18n [json檔] 的 key
        title: '公司簡介', // 頁面標題
        icon: { icon: 'at-outline', pack: 'eva' }, // 菜單圖示
        link: '/home/about', // 路由連結
    },
    {
        key: 'TENANT.TITLE', // 對應 i18n [json檔] 的 key
        title: '租戶管理', // 頁面標題
        icon: { icon: 'briefcase-outline', pack: 'eva' }, // 菜單圖示
        link: '/home/tenant', // 路由連結
    },
    {
        key: 'LAND.TITLE', // 對應 i18n [json檔] 的 key
        title: '土地管理', // 頁面標題
        icon: { icon: 'bar-chart-2-outline', pack: 'eva' }, // 菜單圖示
        link: '/home/land', // 路由連結
    },
    {
        key: 'PUBLICITY.TITLE', // 對應 i18n [json檔] 的 key
        title: '廣告宣傳', // 頁面標題
        icon: { icon: 'radio-outline', pack: 'eva' }, // 菜單圖示
        link: '/home/publicity', // 路由連結
    },
];

路由模組策略

Angular 支援 2 種路由策略,分別是 PathLocationStrategyHashLocationStrategy

PathLocationStrategy 路由策略

PathLocationStrategy - http://localhost:4200/home/about

其中 PathLocationStrategy 路由策略的技術是基於 HTML5 中 history 提供的 history.pushState,簡單來說能將其加入到瀏覽器的歷史裡,又不會真的向伺服器送出請求,是目前主流的路由策略,能更好的配合 Server-Side Rendering 機制的 Angular 專案。

針對未支援 history.pushState 的瀏覽器版本會真的送出請求,導致頁面發生 404 錯誤。

HashLocationStrategy 路由策略

HashLocationStrategy - http://localhost:4200/#/home/about

HashLocationStrategy 這個路由策略是採用 HTML 4 的標準 Hash 網址格式, IE 6 以上都能夠正常瀏覽。

路由模組策略 HashLocationStrategy 設定方式

@NgModule({
    imports: [RouterModule.forRoot(routes, {
        useHash: true
    })],
    exports: [RouterModule],
    providers: []
})
export class AppRoutingModule { }

PathLocationStrategy ng new 時若有選擇加入路由模組會是預設的設定,可參考 my-app


結論

前端框架的路由模組是 SPA 架構中很重要的一部分,Angular 的路由模組則更進一步的提供了延遲載入與預先載入的功能,讓開發者可以更彈性的設定專案需要的路由方式,而且只需要透過簡單的設定就能使用,這就是使用前端框架的好處。

有了路由模組的基本概念之後,接下來會探討延遲載入與預先載入和路由守衛的功能。


參考

Common Routing Tasks

Single Page Application 的應用

SPA單頁面

PathLocationStrategy

HashLocationStrategy

LocationStrategy

路由策略


上一篇
共用元件的動態載入(2)
下一篇
探討路由模組載入策略
系列文
angular專案開發指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言