概要
Vue を使ったアプリケーションで多言語対応を行う方法について解説します。
Vue I18n
Vue I18n は Vue アプリケーションを多言語対応するためのプラグインです。
使い方
1. プロジェクトを作成する
チュートリアル用に作成したサンプルをベースに使用します。
git clone https://github.com/nekobean/vue2-minimum-sample.git
cd vue2-minimum-sample
ディレクトリ構造は vue-cli で生成したもので、以下のようになっています。
├─ .gitignore
├─ babel.config.js
├─ jsconfig.json
├─ LICENSE
├─ package-lock.json
├─ package.json
├─ public
│ ├─ favicon.ico
│ └─ index.html
├─ README.md
├─ src
│ ├─ App.vue
│ ├─ assets
│ ├─ components
│ └─ main.js
└─ vue.config.js
2. Vue I18n をインストールする
npm i vue-i18n@8
3. ロケールデータを定義する
main.js
に以下の記述を追加します。
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
また、言語コードごとに、キーとそれに対応する文字列を定義したオブジェクトを作成します。
言語コードは ISO 639-1コード一覧 で確認できます。
以下の例では、英語 (言語コード en
) では、キー message.hello
に「Hello World」、日本語 (言語コード ja
) では、キー message.hello
に「こんにちは世界」が定義されています。
このオブジェクトを VueI18n オブジェクトを作成する際のコンストラクタに渡します。
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
Vue.config.productionTip = false
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
const i18n = new VueI18n({
locale: 'ja',
messages: messages,
})
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
4. ロケールデータを使用する
$t(キー)
で先程定義したキーに対応する文字列が得られます。
/src/App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./components/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
/src/components/Home.vue
<template>
<p>{{ $t("message.hello") }}</p>
</template>
<script>
export default {
name: "Home",
};
</script>
出力
こんにちは世界
単一のコンポーネントでのみ使用するロケールデータを定義する
最初の例では、main.js 内にロケールデータを定義し、VueI18n のコンストラクタに渡しました。このロケールデータは、すべてのコンポーネントから参照できます。 あるコンポーネントでしか使用しないロケールデータは、そのコンポーネント内でロケールデータを定義することもできます。 main.js で定義したロケールデータとコンポーネントで定義したロケールデータで同じキーがある場合、コンポーネントで定義したロケールデータが優先されます。
コード
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
Vue.config.productionTip = false
const messages = {
en: {
message: {
hello: 'hello world (global)'
}
},
ja: {
message: {
hello: 'こんにちは、世界 (global)'
}
}
}
const i18n = new VueI18n({
locale: 'ja',
messages: messages,
})
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
/src/App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./components/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
/src/components/Home.vue
<template>
<div>
<p>{{ $t("message.hello") }}</p>
<p>{{ $t("message.hoge") }}</p>
</div>
</template>
<script>
export default {
name: "Home",
i18n: {
messages: {
en: {
message: {
hello: "hello world (component)",
hoge: "hoge (component)",
},
},
ja: {
message: {
hello: "こんにちは、世界 (component)",
hoge: "ほげ (component)",
},
},
},
},
};
</script>
出力
こんにちは、世界 (component)
ほげ (component)
複数のコンポーネントで使用するロケールデータを定義する
複数のコンポーネントで使用するロケールデータは、別ファイルでロケールデータを定義し、それを import してsharedMessages プロパティに設定します。
コード
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
Vue.config.productionTip = false
const i18n = new VueI18n({
locale: 'ja'
})
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
/src/App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./components/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
/src/locales/common.js
export default {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
./components/Home.vue
<template>
<div>
<p>{{ $t("message.hello") }}</p>
</div>
</template>
<script>
import commonMessages from "../locales/common";
export default {
name: "Home",
i18n: {
sharedMessages: commonMessages,
},
};
</script>
出力
こんにちは、世界 (component)
言語を動的に切り替える
使用する言語の初期値は VueI18n のコンストラクタの locale
プロパティの値が使用されます。
あとから言語を変更する場合は $i18n.locale
の言語コードを変更します。
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
Vue.config.productionTip = false
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
const i18n = new VueI18n({
locale: 'ja',
messages: messages,
})
new Vue({
i18n,
render: h => h(App)
}).$mount('#app')
/src/App.vue
<template>
<div>
<Home />
</div>
</template>
<script>
import Home from "./components/Home";
export default {
name: "App",
components: {
Home,
},
};
</script>
/src/components/Home.vue
<template>
<div class="locale-changer">
<select v-model="$i18n.locale">
<option v-for="(lang, i) in langs" :key="i" :value="lang">
{{ lang }}
</option>
</select>
<p>{{ $t("message.hello") }}</p>
</div>
</template>
<script>
export default {
name: "Home",
data() {
return { langs: ["ja", "en"] };
},
};
</script>
出力
こんにちは世界
コメント