###### tags: `VUE`
# Vue i18n
在專案內建立屬於 i18n 資料夾,這是目前的結構
專案
│ App.vue
│ main.js
│
├─components
│ └─client
│ │ Menu.vue
│ │
├─i18n
│ │ index.js
│ │
│ ├─lang
│ │ en_US.js
│ │ vi_VN.js
│ │ zh_CN.js
│ │ zh_TW.js
│
└─views
│
├─client
│ Game.vue
│ Index.vue
│ Layout.vue
## 1. JS 格式
### main.js
```javascript=
import Vue from 'vue'
import i18n from './i18n'
import router from './router'
import store from './store'
import App from './App.vue'
new Vue({
router,
store,
i18n,
render: h => h(App),
}).$mount('#app')
```
### i18n -> index.js
從 console.log 的資料,所以在 vue 檔可以使用 `$t('default.lang.header.賠率')` 或是 `$t('locale.lang.header.賠率')` 都能執行

```javascript=
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
// 找 i18n 底下的 lang 資料夾抓出所有 js 檔進行合併成 messages
function loadLocaleMessages() {
const locales = require.context('./lang', true, /[A-Za-z0-9-_,\s]+\.js$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
// 判斷預設值,看 localStorage 是否有 language 值,有就抓 localStorage 沒有就預設 zh_TW
const lang = localStorage.getItem('language') || 'zh_TW'
const i18n = new VueI18n({
locale: lang, // 預設值
messages: loadLocaleMessages(), // 語系包
fallbackLocale: 'zh_TW', // 如果沒有該語系會返回 zh_TW 語系
silentTranslationWarn: true, // 取消錯誤時 console.log 的警告
})
export default i18n
```
### i18n -> lang -> en_US.js、vi_VN.js、zh_CN.js、zh_TW.js
以下只用 2 個語系檔作範例
```javascript=
// zh_TW.js
export const locale = {
lang: {
header: {
離開: '離開',
},
}
}
export default locale
// zh_CN.js
export const locale = {
lang: {
header: {
離開: '离开',
},
}
}
export default locale
```
### Menu.vue
不論是切換哪國語系都可以立馬切換


```htmlmixed=
<p style="color: #fff; padding: 1rem;">
default : {{ $t('default.lang.header.離開') }} <br>
locale : {{ $t('locale.lang.header.離開') }}
</p>
<b-dropdown-item
v-for="(item, key) in LangList"
:key="key"
:data-lang="key"
@click="changeLang($event)"
>
{{ item }}
</b-dropdown-item>
<script>
export default {
data() {
return {
webLang: 'zh_TW',
LangList: {
zh_TW: '繁體中文',
zh_CN: '簡体中文',
en_US: 'English',
vi_VN: 'Tiếng Việt',
},
}
},
methods: {
changeLang(el) {
const selectLang = el.target.dataset.lang
this.webLang = selectLang
this.$i18n.locale = selectLang
this.$store.commit('lang/CHANGE_LANG', selectLang)
localStorage.setItem('language', selectLang)
},
},
}
</script>
```
## 2. json 格式
### main.js
```javascript=
import Vue from 'vue'
import i18n from './i18n'
import router from './router'
import store from './store'
import App from './App.vue'
new Vue({
router,
store,
i18n,
render: h => h(App),
}).$mount('#app')
```
### i18n -> index.js
從 console.log 的資料,所以在 vue 檔可以使用 `$t('header.離開')` 或是 `$t('header.離開')` 都能執行

```javascript=
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
// 找 i18n 底下的 lang 資料夾抓出所有 json 檔進行合併成 messages
function loadLocaleMessages() {
const locales = require.context('./lang', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
// 判斷預設值,看 localStorage 是否有 language 值,有就抓 localStorage 沒有就預設 zh_TW
const lang = localStorage.getItem('language') || 'zh_TW'
const i18n = new VueI18n({
locale: lang, // 預設值
messages: loadLocaleMessages(), // 語系包
fallbackLocale: 'zh_TW', // 如果沒有該語系會返回 zh_TW 語系
silentTranslationWarn: true, // 取消錯誤時 console.log 的警告
})
export default i18n
```
### i18n -> lang -> en_US.json、vi_VN.json、zh_CN.json、zh_TW.json
以下只用 2 個語系檔作範例
```javascript=
// zh_TW.json
{
"header": {
"離開": "離開"
}
}
// zh_CN.json
{
"header": {
"離開": "离开"
}
}
```
### Menu.vue
不論是切換哪國語系都可以立馬切換


```htmlmixed=
<p style="color: #fff; padding: 1rem;">
default : {{ $t('header.離開') }} <br>
locale : {{ $t('header.離開') }}
</p>
<b-dropdown-item
v-for="(item, key) in LangList"
:key="key"
:data-lang="key"
@click="changeLang($event)"
>
{{ item }}
</b-dropdown-item>
<script>
export default {
data() {
return {
webLang: 'zh_TW',
LangList: {
zh_TW: '繁體中文',
zh_CN: '簡体中文',
en_US: 'English',
vi_VN: 'Tiếng Việt',
},
}
},
methods: {
changeLang(el) {
const selectLang = el.target.dataset.lang
this.webLang = selectLang
this.$i18n.locale = selectLang
this.$store.commit('lang/CHANGE_LANG', selectLang)
localStorage.setItem('language', selectLang)
},
},
}
</script>
```
## 手動匯入
其餘檔案不用修改只需要注意語系檔即可
### i18n -> index.js
```javascript=
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { locale as zh_TW } from './zh_TW'
import { locale as zh_CN } from './zh_CN'
import { locale as en_US } from './en_US'
import { locale as vi_VN } from './vi_VN'
Vue.use(VueI18n)
let messages = {}
const messages = {
zh_TW,
zh_CN,
en_US,
vi_VN,
}
const lang = localStorage.getItem('language') || 'zh_TW'
const i18n = new VueI18n({
locale: lang,
messages,
fallbackLocale: 'zh_TW',
silentTranslationWarn: true,
})
export default i18n
```
### i18n -> lang -> en_US.js、vi_VN.js、zh_CN.js、zh_TW.js
以下只用 2 個語系檔作範例
```javascript=
// zh_TW.js
export const locale = {
lang: {
header: {
離開: '離開',
},
}
}
export default locale
// zh_CN.js
export const locale = {
lang: {
header: {
離開: '离开',
},
}
}
export default locale
```
## 結尾
不論是 JS 還是 JSON 格式都能正常運行,只是格式會有所不同。