在 Vue-cli 中使用 i18n 實作多國語系
這篇文主要記錄在 Vue-cli
中使用 i18n
的方式,Vue i18n
官方文件中有提供 Vue-cli 3
專用的 vue add i18n
,這篇文則會使用 vue-cli 3
但基於 npm
安裝的方式。
建立好 Vue-cli
專案後,於根目錄下開啟終端機,安裝 vue-i18n
:
npm install vue-i18n
在根目錄下,建立 common
資料夾,接著建立 config
, plugins
資料夾。config
資料夾中建立 i18n
資料夾,這個資料夾會是我們多國語系每一個檔案的存放處;plugins
則會放入 vue-i18n
的設定檔:
這篇文我們以中文(台灣)及英文為例子。在 i18n
資料夾中建立 tw.js
、 en.js
兩個檔案,於 en.js
加入以下程式碼:
// en.js
export const locale = {
GENERAL: {
NAV_OPTIONS: ['Home', 'About', 'Contact'],
WELCOME_WORD: 'Welcome to your Vue.js application',
OK: 'ok',
CONTINUE: 'continue',
CANCEL: 'cancel',
GUEST: 'guest',
},
}
tw.js
// tw.js
export const locale = {
GENERAL: {
NAV_OPTIONS: ['首頁', '關於', '聯絡我們'],
WELCOME_WORD: '歡迎來到 Vue.js 應用程式',
OK: '好',
CONTINUE: '繼續',
CANCEL: '取消',
GUEST: '訪客',
},
}
在 plugins 建立 vue-i18n.js,加入以下程式碼:
import Vue from 'vue'
import VueI18n from 'vue-i18n'import { locale as en } from '@/common/config/i18n/en'
import { locale as tw } from '@/common/config/i18n/tw'Vue.use(VueI18n)let messages = {}
messages = { ...messages, en, tw }const lang = localStorage.getItem('language') || 'tw'const i18n = new VueI18n({
locale: lang,
messages,
})export default i18n
將我們的語言 import
至 vue-i18n.js
中,接著將其放入 messages
物件中,語言部份則透過 localStorage
取得,並將預設值設定為 tw
。 vue-i18n
會幫我們把我們在 common/config/i18n
中的資料引入。
到 main.js
,將我們設定好的 i18n
引入,並加入至 Vue instance
中:
import Vue from 'vue'
import App from './App.vue'
import i18n from './common/plugins/vue-i18n'Vue.config.productionTip = falsenew Vue({
i18n,
render: (h) => h(App),
}).$mount('#app')
接著我們就能在任何一個組件中,使用 $t(‘鍵’)
的方式直接取得我們在 tw.js
或 en.js
中輸入的值。例如:
// HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ $t('GENERAL.OK') }}</h1>
</div>
</template>
跑 npm run serve
,到前台應該可以看到
接著把 locale
中所有的值引入:
// HelloWorld.vue
<template>
<div class="hello">
<ul>
<li
v-for="(menuItem, index) in $t('GENERAL.NAV_OPTIONS')"
:key="index + 1"
>
{{ menuItem }}
</li>
</ul>
<h1>{{ msg }}</h1>
<h1>{{ $t('GENERAL.OK') }}</h1>
<h1>{{ $t('GENERAL.CONTINUE') }}</h1>
<h1>{{ $t('GENERAL.CANCEL') }}</h1>
<h1>{{ $t('GENERAL.GUEST') }}</h1>
</div>
</template>
其中可以注意到 i18n
可接受的不僅有字串,亦可以傳入陣列或其他資料型態,如 GENERAL.NAV_OPTIONS
的值為 [‘首頁’, ‘關於’, ‘聯絡我們’]
,並在模板中使用 v-for
引入。
亦可以用資料綁定的方式傳入子組件:
// App.vue
<template>
<div id="app">
<HelloWorld :msg="$t('GENERAL.WELCOME_WORD')" />
</div>
</template>
最後加入切換語言的按鈕。加入兩個 button
:
// HelloWorld.vue
<template>
<div class="hello">
<ul>
<li
v-for="(menuItem, index) in $t('GENERAL.NAV_OPTIONS')"
:key="index + 1"
>
{{ menuItem }}
</li>
</ul>
<h1>{{ msg }}</h1>
<h1>{{ $t('GENERAL.OK') }}</h1>
<h1>{{ $t('GENERAL.CONTINUE') }}</h1>
<h1>{{ $t('GENERAL.CANCEL') }}</h1>
<h1>{{ $t('GENERAL.GUEST') }}</h1>
<div>
<button data-lang="tw" @click="setLang">中文</button>
<button data-lang="en" @click="setLang">English</button>
</div>
</div>
</template>
加入兩個 methods
,setActiveLanguage
會將 localStorage
中的 lang
設定為傳入的參數;setLang
則會將 button
的 dataset.lang
值傳入 setActiveLanguage
,並在最後重整網頁。
methods: {
setActiveLanguage(lang) {
localStorage.setItem('language', lang)
},
setLang(evt) {
const lang = evt.target.dataset.lang
this.setActiveLanguage(lang)
return history.go(0)
},
}
實測:
對 vue-i18n
的初步使用介紹就到這邊,實際上使用我覺得最麻煩的應該是翻譯及把現有專案模板或其他地方的值一個個替換,據使用過的同事所述是「非常花時間的事情」。
如果這篇文有任何錯誤,再麻煩觀看的人指出,我會盡快修正,希望能幫助到大家,謝謝。