--- title: '11/09 VueJS 教學筆記: i18n 多語系套件' disqus: hackmd --- 11/09 VueJS 教學筆記: i18n 多語系套件 === 綱要 [TOC] 安裝 i18n 套件和 js-cookie --- `npm install vue-i18n --save` `npm install js-cookie --save` 在專案的`src`下新建一個`lang`的目錄,並在其中建立: `index.js` `en.js` `jp.js` `zh_tw.js` 建構語系設定 --- **zh_tw.js** ```javascript= module.exports = { header: 'Vue i18n 多語管理', select_language: '選擇語言', change_language: '切換語言', please_select: '請選擇', locale_en: 'English', locale_zh_tw: '繁體中文', locale_jp: '日文' } ``` **en.js** ```javascript= module.exports = { header: 'Vue i18n Multi Language', select_language: 'select language', change_language: 'change language', please_select: 'please select', locale_en: 'English', locale_zh_tw: 'Chinese(Traditional)', locale_jp: 'Japenese' } ``` **jp.js** ```javascript= module.exports = { header: 'Vue i18n 多言語機能', select_language: '言語選択', change_language: '言語切替', please_select: '言語を選んでください', locale_en: '英語', locale_zh_tw: '中国語(台湾)', locale_jp: '日本語' } ``` **index.js** ```javascript= import Vue from 'vue' // 前面cookies與local storange課程有用到,直接調用 import Cookies from 'js-cookie' import VueI18n from 'vue-i18n' import twLocale from './zh_tw' import enLocale from './en' import jpLocale from './jp' // 課程中都有使用到element UI,這裡需要element UI 的locale設置 import locale_TW from 'element-ui/lib/locale/lang/zh-TW' import locale_EN from 'element-ui/lib/locale/lang/en' import locale_JA from 'element-ui/lib/locale/lang/ja' import locale from 'element-ui/lib/locale' // 全域啟用i18n Vue.use(VueI18n) // element UI 所使用的多語切換 i18n.t(key, value) = $t(key, value) locale.i18n((key, value) => i18n.t(key, value)) // 定義語系使用的key name,我們可以將外部的語系檔案在 messages 中引用 const messages = { en: { ...enLocale, ...locale_EN }, zh_tw: { ...twLocale, ...locale_TW }, jp: { ...jpLocale, ...locale_JA } } const languageKey = 'language' // 定義寫入Cookies時使用的名稱 const chooseLanguage = Cookies.get('language') // 定義取得Cookies的常數 // 定義取得Cookies的函數並匯出 export const getLanguage = () => { Cookies.get(languageKey) if (chooseLanguage) { return chooseLanguage } // 如果沒有選擇任何一項語言 const language = (navigator.language).toLowerCase() // 將瀏覽器回傳語value字串統一為小寫 const locales = Object.keys(messages) // { en, zh_tw, jp } for (const locale of locales) { if (language.indexOf(locale) > -1) { return locale } } return 'zh_tw' // 沒選擇語言的時候,預設轉到繁體中文 } // 定義設置Cookies的函數並匯出,之後我們會在各組件中呼叫它來使用 export const setLanguage = (language) => { i18n.locale = language Cookies.set(languageKey, language) } const i18n = new VueI18n({ // set locale // options: en | zh | es locale: getLanguage(), messages, // 避免i18n會因為一點小事刷你整頁的console silentTranslationWarn: true }) export default i18n ``` 接著到`main.js`繼續做以下設定,這樣基本的配置就完成了: **main.js** ```javascript= // ... // ... import i18n from './lang' // ... new Vue({ el: '#app', // ... i18n, render: h => h(App) }) ``` 開始在組件中使用 --- **VueI18n.vue** [Github範例](https://github.com/fortes1219/vue_0803/blob/0803/src/components/home/VueI18n.vue) template部分: ```htmlmixed= <template> <div class="page vue_i18n"> <!--$t(key.value)--> <h1>{{ $t('header') }}</h1> <br /> <div class="row horizontal v_center"> <el-form style="width: 500px;"> <el-form-item label="選擇語言"> <!--如果對象是label、value、placeholder等,必須改為v-bind:label ...etc--> <el-select v-model="langSelect.select" :placeholder="$t('please_select')" clearable> <el-option v-for="(item, index) in langSelect.items" :key="index" :value="item.value" :label="item.label" /> </el-select> <el-button type="primary" @click="changeLanguage(langSelect.select)" >{{ $t('change_language') }}</el-button> </el-form-item> </el-form> </div> </div> </template> ``` JS部分: ```javascript= // 引入我們在 lang >> index.js 中設置與取得語系的function import { getLanguage, setLanguage } from "../../lang" export default { name: "VueI18n", data() { return { langSelect: { select: "", items: [ // JS中引用的 i18n 則需改為 this.$t(key.value) { value: "zh_tw", label: this.$t("locale_zh_tw") }, { value: "en", label: this.$t("locale_en") }, { value: "jp", label: this.$t("locale_jp") } ] } } }, // created階段就先取得Cookies中記錄的語系 created() { getLanguage }, methods: { changeLanguage(val) { setLanguage(val) // 由於更新語系函數執行後不會更新所有DOM,讓網頁refresh後就沒這個問題 location.reload() } } } ``` ![](https://i.imgur.com/hP8x3bT.png) ![](https://i.imgur.com/l5DFx1D.png) ###### tags: `VueJS` `i18n`