Vue3 中使用 router.push 傳遞帶參數的物件(object)方法

在 Vue 3 中使用 router.push 傳遞帶參數的物件時,必須使用 JSON 序列化(use JSON serialization),因為路由參數(params)僅支援 URL 中的字串或數字。或者,對於不需要出現在 URL 中的複雜數據,可以使用全域 store,例如 Pinia 或 Vuex。

使用帶有序列化參數的 router.push,這是透過參數傳遞物件最常用的方法,但它會將資料暴露在 URL 路徑中。

step01: 在發送頁面(組件)中的程式

在將物件傳遞給 router.push() 之前,使用 JSON.stringify() 進行序列化。必須使用路由名稱(name),因為 router.push 中的參數不能與路徑(path)一起使用。

Vue
<script setup>
import { useRouter } from 'vue-router';

const router = useRouter();
const userObject = { id: 1, name: 'Eduardo', role: 'admin' };

const navigateToUser = () => {
  router.push({
    name: 'UserDetail', // Must use the route name
    params: {
      userData: JSON.stringify(userObject) // Serialize the object
    }
  });
};
</script>

step02: 在路由上的設定

使用動態路由,例如 /:userData 來定義傳遞的方式,以便接收傳入的參數。可以在 props 中,可以事先定義接收到傳入的物件時,要作 JSON.parse

JavaScript
import UserDetail from './views/UserDetail.vue';

const routes = [
  {
    path: '/user/:userData', // Dynamic segment
    name: 'UserDetail',
    component: UserDetail,
    // Optional: Pass params as props to the component for cleaner access
    props: route => ({
      userData: JSON.parse(route.params.userData)
    })
  }
];

step03: 在接收頁面使用 defineProps 接收參數

透過將 JSON 字串解析回 JavaScript 物件來存取資料。如果在路由器設定中使用 props: true:

Vue
<script setup>
import { defineProps } from 'vue';

// The prop name must match the param name in the route path
const props = defineProps({
  userData: Object // Vue automatically parses it if configured with a function
});

console.log(props.userData.name);
</script>

step04: 在接收頁面使用 useRoute 接收參數

如果直接透過 useRoute() 存取

Vue
<script setup>
import { useRoute } from 'vue-router';
import { computed } from 'vue';

const route = useRoute();
const userData = computed(() => {
  return JSON.parse(route.params.userData);
});

console.log(userData.value.name);
</script>

這樣就可以跨頁面傳遞物件(object)值了!!

傳遞參數時自動加解密

使用帶有序列化參數的 router.push,這是透過參數傳遞物件最常用的方法,但它會將資料暴露在 URL 路徑中。為了安全起見,可以使用套件 crypto-js 來作加密傳輸。

useCrypto.js 範例

JavaScript
// useCrypto.js
import CryptoJS from 'crypto-js'

const SECRET_KEY = 'MY_SECRET_KEY_123' // 建議改成 import.meta.env.VITE_SECRET_KEY

export function useCrypto() {
  const encrypt = (data) => {
    const text = JSON.stringify(data)
    return CryptoJS.AES.encrypt(text, SECRET_KEY).toString()
  }

  const decrypt = (cipherText) => {
    try {
      const bytes = CryptoJS.AES.decrypt(cipherText, SECRET_KEY)
      const text = bytes.toString(CryptoJS.enc.Utf8)
      return JSON.parse(text)
    } catch (e) {
      console.error('Decrypt failed', e)
      return null
    }
  }

  return {
    encrypt,
    decrypt,
  }
}

使用方式

JavaScript
const orderParams = {
	dept: recDept,
	emp: recEmp
};    
// 導向點餐頁面
router.push({ name: 'ToOrder', params: { orderParams: encrypt(orderParams) } } ); A

useCrypto.ts 範例

TypeScript
import CryptoJS from 'crypto-js'

const SECRET_KEY = import.meta.env.VITE_SECRET_KEY

if (!SECRET_KEY) {
  console.warn('[useCrypto] VITE_SECRET_KEY is not defined')
}

export function useCrypto() {
  const encrypt = (data: unknown): string => {
    const text = JSON.stringify(data)
    return CryptoJS.AES.encrypt(text, SECRET_KEY).toString()
  }

  const decrypt = <T = any>(cipherText: string): T | null => {
    try {
      const bytes = CryptoJS.AES.decrypt(cipherText, SECRET_KEY)
      const text = bytes.toString(CryptoJS.enc.Utf8)
      return JSON.parse(text)
    } catch (e) {
      console.error('[useCrypto] decrypt failed', e)
      return null
    }
  }

  return {
    encrypt,
    decrypt,
  }
}

ts 常見錯誤

TypeScript
// 錯誤 1:用 process.env
process.env.VITE_SECRET_KEY

// 錯誤 2:env 變數未重啟
VITE_SECRET_KEY=xxx
//但沒重啟:
npm run dev

//錯誤 3:忘了 VITE_ 前綴
SECRET_KEY=xxx

TS 專案型別補強(可選)

①若你用 TypeScript,避免型別警告:檔名一定要是 .d.ts 例如: env.d.ts

TypeScript
// env.d.ts
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_SECRET_KEY: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

② 確認 tsconfig.json 有包含它

JSON
{
  "compilerOptions": {
    "types": ["vite/client"]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.vue"
  ]
}

③ 重啟 TypeScript Server / Dev Server(非常重要)

Bash
npm run dev

或在 VS Code:

Bash
Ctrl + Shift + P  TypeScript: Restart TS Server

為什麼一定要這樣做?

錯誤來源

TypeScript
import.meta.env.VITE_SECRET_KEY
// ❌ TS 預設不知道 env 是什麼

加上這行就「全解」

TypeScript
/// <reference types="vite/client" />

Vite 會幫你宣告:

TypeScript
interface ImportMeta {
  readonly env: ImportMetaEnv
}

總結一句話

TypeScript
Vite + TS一定要有 /// <reference types="vite/client" />

小提醒(實務建議)

  • 不要把真正敏感資料(token、密碼)放在 query
  • SECRET_KEY 請改用 .env
  • Vite 專案 → import.meta.env.VITE_XXX
  • 修改 .env一定要重啟
  • 前端加密 → 只能防君子

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


內容索引