###### 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.賠率')` 都能執行 ![](https://i.imgur.com/cKvCL8U.png) ```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 不論是切換哪國語系都可以立馬切換 ![](https://i.imgur.com/YiSgSQl.png) ![](https://i.imgur.com/YTg9Hfh.png) ```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.離開')` 都能執行 ![](https://i.imgur.com/DwZfvpG.png) ```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 不論是切換哪國語系都可以立馬切換 ![](https://i.imgur.com/YiSgSQl.png) ![](https://i.imgur.com/YTg9Hfh.png) ```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 格式都能正常運行,只是格式會有所不同。