如果你正在用 Vue 3 + Vite 打造後台系統,某天產品要賣到海外、或是要同時支援簡體、繁體、英文,你會發現「把文字寫死在模板裡」是第一個災難——等到要改語言時,得在幾百個元件裡逐行替換。這篇文章就用實戰步驟,帶你把多語言架構一次打好。
一、什麼是 i18n,為什麼需要它
i18n 是 internationalization 的縮寫(i 與 n 中間有 18 個字母)。它本質上是一套「把顯示文字從程式碼抽離」的機制:所有會出現在畫面上的文案,都集中放在語言包(message bundle)裡,程式只負責「按 key 取值」,再由框架根據當前語言渲染對應文字。
- 對開發者:文案與邏輯解耦,改語言不必動程式。
- 對翻譯團隊:只需維護幾份 JSON,不必讀原始碼。
- 對產品:上線後能動態切換,甚至按使用者偏好記住語言。
二、用 Vue I18n 搭建多語言骨架
重點:Vue 3 請安裝 vue-i18n@9,它原生支援 Composition API。下面三步把骨架立起來。
步驟 1:安裝依賴
npm i vue-i18n@9
步驟 2:建立 i18n 實例與語言包
// i18n/index.js
import { createI18n } from 'vue-i18n'
const messages = {
'zh-TW': { greeting: '歡迎回來', save: '儲存' },
'en': { greeting: 'Welcome back', save: 'Save' },
'zh-CN': { greeting: '欢迎回来', save: '保存' },
}
export const i18n = createI18n({
legacy: false,
locale: 'zh-TW',
fallbackLocale: 'en',
messages,
})
步驟 3:在 main.js 掛載
import { createApp } from 'vue'
import { i18n } from './i18n'
createApp(App).use(i18n).mount('#app')
三、在元件中使用多語言
Composition API 下用 t() 取文字,模板與 script 都一樣直覺:
<template>
<h1>{{ t('greeting') }}</h1>
<button>{{ t('save') }}</button>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
重點:遇到帶變數的句子(如「您有 3 筆待辦」),用具名插值 t('todo', { n: 3 }),避免把數字硬拼進字串,這在英文單複數處理上尤其重要。
四、動態切換語言
切換只需改 locale,畫面會自動重渲染:
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
function changeLang(l) {
locale.value = l
localStorage.setItem('lang', l) // 記住使用者偏好
}
五、用 Vite 自動載入翻譯檔
當語言包變多,手動 import 很痛苦。重點:用 Vite 的 import.meta.glob 一次匯入整個資料夾,新增語言檔不必改任何程式:
const modules = import.meta.glob('./locales/*.json', { eager: true })
const messages = {}
for (const path in modules) {
const lang = path.split('/').pop().replace('.json', '')
messages[lang] = modules[path].default
}
這正是大型後台(如 Vben Admin 系列)處理多語言的慣用手法,翻譯檔隨建隨用。
六、常見陷阱與最佳實踐
- key 要有意義且分層(
user.list.title),別用text1、text2。 - 永遠設
fallbackLocale,缺譯時降級而非空白。 - 日期、數字、金額請用
IntlAPI 或 i18n 的datetimeNumberFormats,別自己格式化。 - 語言包體積大時,考慮按需載入(動態 import)而不是全部打包。
互動話題:你的專案目前支援幾種語言?在處理多語言時,踩過最痛的坑是什麼?歡迎在留言區分享,我們一起把國際化做得更順手!