Skip to content

Vue 3 入門指南:掌握 Vue Router 靜態路由設定

Vue Router 靜態路由:createWebHistory 設定

在開發單頁應用程式(SPA)時,路由管理是不可或缺的一環。本文將帶領您從零開始,完成 Vue Router 的基本環境設定,並學會如何建立穩健的靜態路由架構。若還沒安裝套件,請先看 Vue Router 介紹

規劃檔案架構

在開始撰寫程式碼前,良好的目錄規劃能提升專案的可維護性。建議在 src 目錄下新增 routerviews 目錄:

  • router/:存放路由設定檔。
  • views/:存放對應路由的頁面元件。
src/
 ├─ router/
 │   └─ index.js    # 路由核心配置
 ├─ views/
 │   ├─ Home.vue    # 首頁元件
 │   └─ About.vue   # 關於頁面元件
 ├─ App.vue         # 根元件(包含導覽與渲染區)
 └─ main.js         # 應用程式入口

建立頁面元件 (Views)

首先,我們準備兩個基礎頁面內容,分別是 首頁關於我們

Home.vue

vue
<template>
  <h1>Home</h1>
  <p>這是專案的首頁內容。</p>
</template>

About.vue

vue
<template>
  <h1>About</h1>
  <p>這是關於我們的頁面說明。</p>
</template>

設定 Vue Router 路由配置

/router/index.js 中,我們需要定義路由的模式與對應路徑。

選擇路由模式:History vs Hash

  • Hash: createWebHashHistory() 優點是不需要有後端設定,缺點為 URL 中會有 #,較不符合主流的使用。
  • History (推薦): createWebHistory() 優點符合主流使用,缺點是需要後端伺服器配合處理 fallback,例如:IIS、Apache、Nginx。

History 模式最常見的災難:重新整理就 404

前端切換沒問題,但使用者在 /about 按下重新整理時,瀏覽器會 真的向伺服器請求 /about,而伺服器上並沒有這個檔案。解法是在伺服器設定 fallback,把找不到的路徑都回傳 index.html,剩下的交給前端路由判斷。若部署環境無法這樣設定,就改用 Hash 模式。

路由設定程式碼

js
// /router/index.js
import { createRouter, createWebHistory } from 'vue-router';

export default createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('@/views/Home.vue'),
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('@/views/About.vue'),
    },
    {
      path: '/:pathMatch(.*)*',
      redirect: '/',
    },
  ],
});

什麼是 /:pathMatch(.*)*

這是一個特殊的正則匹配語法,通常用來處理 未匹配的路由

  • 代表動態參數,也就是把匹配到的路徑 存到一個叫 pathMatch 的參數裡。例如:/abc/def 變成 route.params.pathMatch
  • (.*): 它是個正規表達式,意思是 匹配任何字元
  • *: 為 Vue Router 的特殊語法,表示可以 匹配多層路徑。例如:/abc/abc/def/abc/def/ghi

WARNING

路由匹配是由上而下的,因此,/:pathMatch(.*)* 務必放在 routes 陣列的最末端。

兩個容易被忽略的設定

路由表裡有兩個寫法看起來只是習慣,其實各有實質好處:

  • name 具名路由:跳轉時寫 router.push({ name: 'about' }),日後路徑從 /about 改成 /about-us 時,所有連結都不用改
  • component: () => import(...) 懶載入:這個寫法會把頁面拆成獨立的檔案,使用者 真正進入該頁時才下載,能有效縮短首次載入時間。若寫成頂部 import 一次匯入,所有頁面都會被打包進首屏。

註冊並啟動路由

main.js 中匯入我們寫好的路由物件,並使用 .use() 進行安裝。

js
...
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 匯入路由設定

const app = createApp(App);
app.use(router); // 掛載路由
app.mount('#app');

app.use() 是 Vue 安裝外掛的統一入口,詳細機制可參考 建立應用程式

在頁面中呈現路由內容

最後,我們在 App.vue 使用 Vue Router 提供的核心元件來實作導覽功能。

  • <router-link>: 渲染為 <a> 標籤,點擊時切換路由而不重新整理頁面。
  • <router-view>: 動態顯示目前路由所對應的元件內容。
vue
<template>
  <router-link to="/">Home</router-link>|
  <router-link to="/about">About</router-link>
  <RouterView />
</template>

目前所在頁面要怎麼標記?

Vue Router 會自動為對應的連結加上 router-link-activerouter-link-exact-active 兩個 class,直接寫 CSS 就能標示目前位置,不需要自己判斷。若要依狀態切換樣式,也可以搭配 動態 class

結語

透過以上五個步驟,您已經成功建立了一個具備基本導航與 404 容錯機制的 Vue 3 路由環境。建議在實際專案中,將 404 導向一個專門的 NotFound.vue 頁面,能提供更好的使用者體驗:

js
{
  path: '/:pathMatch(.*)*',
  name: 'not-found',
  component: () => import('@/views/NotFound.vue'),
}

比起 redirect: '/' 直接把人丟回首頁,專屬頁面能明確告知 網址不存在,使用者才不會以為是自己按錯。

接下來若頁面需要帶參數,請看 動態路由;若要做出外殼不變、內容切換的版面,請看 巢狀路由

常見問題

createWebHistory 與 createWebHashHistory 該選哪一個?

能修改伺服器設定就用 createWebHistory,網址乾淨也對 SEO 較友善。若部署環境無法設定 fallback,例如:靜態空間或某些內部平台,改用 createWebHashHistory 讓網址帶 # 才不會重新整理就 404。

為什麼 History 模式重新整理會出現 404?

因為瀏覽器會真的向伺服器請求該路徑,而伺服器上並沒有這個檔案。解法是設定 fallback,把所有找不到的路徑都回傳 index.html,交給前端路由決定畫面。

pathMatch 那一條為什麼要放最後?

路由是由上而下比對,/:pathMatch(.*)* 能匹配任何路徑。若放在前面,所有網址都會先被它接走,後面的路由永遠不會生效。

路由的 name 有必要寫嗎?

建議寫。使用具名路由跳轉時只依賴名稱,日後調整路徑不必回頭修改每個連結,帶參數時也比自己組字串安全。

component 為什麼要寫成箭頭函式?

那是 路由懶載入。寫成 () => import(...) 會讓該頁面被拆成獨立檔案,使用者真正進入時才下載,可縮短首次載入時間。

404 要用 redirect 還是顯示專屬頁面?

建議顯示專屬的 NotFound 頁面。直接導回首頁會讓使用者以為自己按錯,也無法察覺是網址輸入錯誤或連結失效。

延伸閱讀