Vue.js: Vue I18nの公式ドキュメントに見当たらず悩んだふたつのこと

[Vue I18n](https://kazupon.github.io/vue-i18n/)は、Vueアプリケーションを国際化(多言語対応)させるためのプラグインです。ページに表示するテキストを、ロケールに応じて切り替えられます。インストールから基本的な設定と使い方までは「[Vue.js: Vue I18nでアプリケーションを多言語に対応させる](https://qiita.com/FumioNonaka/items/bb994ab520bb0b268f65)」でご説明しました。本稿では、公式ドキュメントに解説が見当たらず悩んだことをふたつ紹介します。

# 01 プレースホルダーを多言語化する
実は、[プレイスホルダーを使うことは推奨されない](https://developer.mozilla.org/ja/docs/Web/HTML/Element/input#htmlattrdefplaceholder)ようです。そうはいっても、入力例を示すなど、使う場面は少なくないでしょう。ところが、つぎのように記述すると、式(`$t('placeholder')`)がそのまま表示されてしまい、翻訳テキストが取り出せませんでした。

```html
<input type="text"
	placeholder="$t('placeholder')">
```

Vue I18nサイトのドキュメントには見当たらず、英語でも情報は多くありません。[Stack Overflow](https://stackoverflow.com/questions/53706390/vue-js-change-placeholder-of-text-input-according-to-v-model-value/53706508#53706508)で見つけたのが、`v-bind`(省略記法`:`)を加えなければならないということです。たったひと文字で、プレースホルダーが多言語化できました。

```html
<input type="text"
	:placeholder="$t('placeholder')">
```


# 02 `t()`メソッドに渡すパスに変数を含める
翻訳テキストを取り出す[`$t()`](https://kazupon.github.io/vue-i18n/api/#t)メソッドの第1引数には、テキストが収められたプロパティのパスを渡します。ここに変数を含めるにはどうしたらよいかです。具体的には、`v-for`ディレクティブで複数要素を変数からつくりたい場合でした。

```html
<div id="app">
 	<ul>
		<li
			v-for="city in cities"
			:key="city">
			<!-- message[city]のテキストを取り出したい -->
		</li>
	</ul>
</div>
```

```js
const messages = {
	en: {
		message: {
			tokyo: 'Tokyo',
			newyork: 'New York',
			london: 'London'
		}
	},
	ja: {
		message: {
			tokyo: '東京',
			newyork: 'ニューヨーク',
			london: 'ロンドン'
		}
	}
}
// ...[中略]...
new Vue({
	i18n,
	data: {cities: ['tokyo', 'newyork', 'london']}
}).$mount('#app')
```

試したところ、つぎの記述で翻訳テキスト「東京」または「Tokyo」が表示されました。

```html
{{ $t("message['tokyo']") }}
```

それならと、つぎのように書いてみると、また式が表れてテキストは取り出せません。

```html
{{ $t("message[city]") }}
```

こちらは検索では見つけることができず、[VueのForum(英語)で質問](https://forum.vuejs.org/t/vue-i18n-doesnt-t-method-accept-a-variable-for-the-path/75518)してみたところ回答が得られました。`messages`オブジェクトの感覚で捉えていたのがよくなかったようです。文字列のパスと考えるべきでした。

```html
{{ $t("message." + city) }}
```

ご参考までにテスト用のサンプルをCodePenに上げておきます。

#### サンプル001■ Vue I18n Test
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="FumioNonaka" data-slug-hash="NWKQwYZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Vue I18n Test">
  <span>See the Pen <a href="https://codepen.io/FumioNonaka/pen/NWKQwYZ">
  Vue I18n Test</a> by Fumio Nonaka (<a href="https://codepen.io/FumioNonaka">@FumioNonaka</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# Appendix TodoMVCを日英対応にする
「[Vue.js + CLI入門](http://www.fumiononaka.com/Business/index.html#Vue_CLI)」は、公式サイト「[TodoMVC の例](https://jp.vuejs.org/v2/examples/todomvc.html)」をVue CLIによる単一ファイルコンポーネント(vueファイル)でつくり直しました。さらに、これをVue I18nで日英対応にしたのが「[Vue.js + Vue I18n: アプリケーションを多言語に対応(国際化)させる](http://www.fumiononaka.com/Business/html5/FN1910002.html)」の作例です。こちらはCodeSandboxに公開しています。興味がある方はリンクの解説をお読みください。

#### サンプル002■ vue-i18n-todo-mvc
[![FN1910002_007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128949/2e970f45-29ae-0563-e46c-dc03794bfbb2.png)](https://codesandbox.io/s/vue-i18n-todo-mvc-7pnti)
[\>\> CodeSandboxへ](https://codesandbox.io/s/vue-i18n-todo-mvc-7pnti)