Vue-i18N 算是採用 Vue 為前端框架者,常會使用的多國語言翻譯套件。不過為了支援 TypeScript 和便於日後維護,筆記下檔案的配置和資料流向。
關鍵點
1. Vuex:紀錄使用者的語系 ( 如:en_us ),並運用 vuex 中的 action 方法來重複呼叫對應的 mutation
2. .vue 元件檔:取用 vuex 中預先寫好的 getter 方法,並將其綁定到 v-model 上。當修改時,將 vuex 中的 action 方法當作 set 的方式,寫回到 vuex 中並同時修改 $i18n 的值。
3. .vue 元件檔中,在 template 中有綁定 $t 的,可以直接使用。其餘的部分,要藉由監聽 vuex 中紀錄使用者語系的變數,顯示對應的變化。初始的預設值,請寫在該元件檔的 data 內。
4. Tsconfig 檔,要新增 “compilerOptions.resolveJsonModule”: true
5. 在根目錄下建立一個 i18n 的資料夾,裏頭放置語系的 json 檔。可以支援多層的 key-value
6. i18n/config 中,會新增兩隻檔案:index.ts / locales.ts 。每當要新增語系時,要修改 locales.ts 中的 enum Locales{} 、LayoutLanguages 和 index.ts 三處即可
示範程式碼
<template> | |
<div class="hello"> | |
<h1>{{ msg }}</h1> | |
<p v-html="headline"></p> | |
<h3>{{ $t("intro.titles.links") }}</h3> | |
<ul> | |
<li v-for="(link, index) in essentialLinks" :key="index"> | |
<a :href="link.url" target="_blank" rel="noopener">{{ link.caption }}</a> | |
</li> | |
</ul> | |
</div> | |
</template> | |
<script lang="ts"> | |
import Vue from 'vue' | |
import { | |
TranslateResult | |
} from 'vue-i18n' | |
import { | |
mapGetters | |
} from 'vuex' | |
import { | |
Link | |
} from '../declarations/HelloWorld' | |
export default Vue.extend({ | |
name: 'HelloWorld', | |
data () { | |
return { | |
headline: this.$t('intro.headline') as TranslateResult, | |
essentialLinks: (this.$t('intro.essentialLinks') as unknown) as Link[] | |
} | |
}, | |
props: { | |
msg: String | |
}, | |
computed: { | |
...mapGetters(['selectedLanguage']) | |
}, | |
watch: { | |
selectedLanguage: function () { | |
this.headline = this.$t('intro.headline') | |
this.essentialLinks = (this.$t('intro.essentialLinks') as unknown) as Link[] | |
} | |
} | |
}) | |
</script> |
// i18n/config/index.ts | |
import { | |
Locales | |
} from './locales' | |
import enUs from '../en_us.json' | |
import zhTw from '../zh_tw.json' | |
import zhCn from '../zh_cn.json' | |
export const messages = { | |
[Locales.enUs]: enUs, | |
[Locales.zhTw]: zhTw, | |
[Locales.zhCn]: zhCn | |
// 若要新增語系,在這邊定義 | |
} | |
// 修改預設語系 | |
export const defaultLocale = Locales.enUs |
// i18n/config/locales.ts | |
interface I18nLanguage { | |
param: string; | |
title: string; | |
} | |
export enum Locales { | |
enUs = 'en_us', | |
zhTw = 'zh_tw', | |
zhCn = 'zh_cn', | |
// 若要新增語系,在這邊定義 | |
} | |
export const LayoutLanguages: Array<I18nLanguage> = [ | |
{ | |
param: Locales.enUs, | |
title: 'English' | |
}, | |
{ | |
param: Locales.zhTw, | |
title: '繁體中文' | |
}, | |
{ | |
param: Locales.zhCn, | |
title: '简体中文' | |
} | |
// 若要新增語系,在這邊定義選單選項 | |
] |
// store/index.ts | |
import Vue from 'vue' | |
import Vuex from 'vuex' | |
// vue-i18n | |
import { | |
Locales | |
} from '@/i18n/config/locales' | |
import { | |
defaultLocale | |
} from '@/i18n/config' | |
Vue.use(Vuex) | |
export default new Vuex.Store({ | |
state: { | |
selectedLanguage: defaultLocale | |
}, | |
getters: { | |
selectedLanguage: state => state.selectedLanguage | |
}, | |
mutations: { | |
setLanguage (state, payload: Locales) { | |
state.selectedLanguage = payload | |
} | |
}, | |
actions: { | |
selectNewDefaultLanguage ({ getters, commit }, lang: Locales) { | |
const { selectedLanguage }: { selectedLanguage: Locales } = getters | |
if (lang !== selectedLanguage) { | |
commit('setLanguage', lang) | |
} | |
} | |
} | |
}) |
Github 位置:https://github.com/andy922200/vue-vuetify-typescript-eslint-babel-stylelint-integration
資料來源
1. Manage Vue i18n with Typescript
2. 在 Vue-cli 中使用 i18n 實作多國語系