跳至主要內容
Skip to content

程式化導航 (Programmatic Navigation)

<router-link> 很好用,但有時候我們需要在程式碼中決定何時跳轉(例如:登入成功後跳回首頁、表單送出後跳到列表頁)。

這時我們就需要用到 Router 實體提供的方法。


一、 獲取 Router 實體

在 Vue 3 Composition API 中:

javascript
import { useRouter } from "vue-router";

const router = useRouter();

NOTE

useRouter 必須在 setup()<script setup> 的頂層呼叫。如果你在一般的函數中呼叫它,會拿到 undefined


二、 核心方法

Vue Router 提供了三個主要方法,它們模仿了原生 window.history API 的行為。

1. router.push(location)

這對應到 history.pushState。它會向 history stack 添加一個新記錄,所以使用者按「上一頁」會回到原本的頁面。

常見用法:

javascript
// 字串路徑
router.push("/home");

// 物件路徑 (更推薦)
router.push({ path: "/home" });

// 帶查詢參數 (Query) -> /register?plan=private
router.push({ path: "/register", query: { plan: "private" } });

// 帶 Hash -> /about#team
router.push({ path: "/about", hash: "#team" });

WARNING

Params 陷阱:如果你使用 pathparams 會被忽略!

javascript
// 錯誤!params 不生效
router.push({ path: "/user", params: { userId: "123" } });

// 正確:配合 name 使用
router.push({ name: "user", params: { userId: "123" } });
// 或者直接組字串
router.push(`/user/${userId}`);

2. router.replace(location)

這對應到 history.replaceState。它會 替換 當前的 history 記錄。 使用者按「上一頁」不會 回到原本的頁面。

適用場景

  • 登入後的重導向(不希望使用者按上一頁回到登入頁)。
  • 表單提交後的狀態變更。
javascript
router.replace({ path: "/home" });

3. router.go(n)

這對應到 history.go(n)。在 history stack 中前進或後退 n 步。

javascript
router.go(1); // 下一頁
router.go(-1); // 上一頁 (等同於 window.history.back())

三、 等待導航完成

router.pushrouter.replace 其實會回傳一個 Promise

這在某些情境下非常有用,例如你需要確保頁面已經切換完畢才執行某些動畫或數據加載。

javascript
await router.push("/about");
console.log("導航完成!現在在 About 頁面");

四、 導航故障 (Navigation Failures)

有時候導航會失敗,例如:

  • 使用者已經在 /home,你又 push('/home')
  • 導航被 beforeEach 守衛攔截 (return false)。

Vue Router 4 不會像 v3 那樣在這些情況下拋出 Error (讓你的 Console 變紅)。它會回傳一個 NavigationFailure 物件。

如果你需要偵測這類情況:

javascript
import { NavigationFailureType, isNavigationFailure } from "vue-router";

const failure = await router.push("/dashboard");

if (failure) {
  if (isNavigationFailure(failure, NavigationFailureType.aborted)) {
    console.log("導航被守衛攔截");
  } else if (isNavigationFailure(failure, NavigationFailureType.duplicated)) {
    console.log("導航重複 (已在該頁面)");
  }
}

總結

  1. 使用 useRouter() 獲取實體。
  2. push 會留歷史記錄,replace 不會。
  3. 注意path 不能與 params 混用,請改用 name 搭配 params

下一章,我們將介紹如何讓路由配置更乾淨解耦:命名視圖 (Named Views)

下一章:命名路由與多重視圖