テンプレート構文

最終更新日: 2017年8月3日

Vue.js では HTML ベースのテンプレート構文を使っているので、Vue インスタンスのデータと描画された DOM を宣言的に対応させることができます。全ての Vue.js テンプレートは、仕様に準拠しているブラウザや HTML パーサによってパースできる有効な HTML です。

内部では、Vue はテンプレートを Virtual DOM の描画関数にコンパイルします。リアクティブシステムと組み合わせて、Vue は再描画に必要なコンポーネントをインテリジェントに把握でき、アプリケーションの状態が変わった時に最低限の DOM 操作を適用します。もし、あなたが Virtual DOM の概要に詳しく、JavaScript で直接描画するのを好む場合、テンプレートの代わりに直接 render 関数で書く ことも可能で、オプションで JSX をサポートしています。

展開

テキスト

データバインディングのもっとも基本的な形は、”Mustache” 構文(二重中括弧)を利用したテキスト展開です:

<span>Message: {{ msg }}</span>

mustache タグは、対応するオブジェクトの msg プロパティの値に置き換えられます。また、msg プロパティが変更される時、それに応じて更新されます。

v-once ディレクティブを使用することで、データ変更時の更新はおこなわず、一度だけ展開することができます。ただし、同じノードのあらゆるバインディングが影響を受けることに注意してください:

<span v-once>This will never change: {{ msg }}</span>

生の HTML

2重中括弧の mustaches は、データを HTML ではなく、プレーンなテキストとして扱います。実際の HTML として出力するためには、v-html ディレクティブを使用する必要があります:

<div v-html="rawHtml"></div>

この div のコンテンツは rawHtml プロパティの値に置き換えられ、プレーンな HTML として解釈されます。Vue は、文字列ベースのテンプレートエンジンではないので、v-html をテンプレート部品を構成して使用できないことに注意しましょう。代わりに、 UI の再利用や組み合わせのための基礎として、コンポーネントを利用することが好ましいです。

XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。

属性

Mustache は、HTML 属性の内部で使用することはできません。代わりに、v-bind ディレクティブを使用してください:

<div v-bind:id="dynamicId"></div>

また、真偽値属性も使用できます。式を評価し、偽とみなせる値のとき、属性を削除します。

<button v-bind:disabled="isButtonDisabled">Button</button>

JavaScript 式の使用

これまで、テンプレートに単純なキーをバインディングしてきました。実際には Vue.js は全てのデータバインディング内部で JavaScript 式を完全にサポートします:

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>

これらの式は、Vue インスタンスが所有するデータスコープ内で JavaScript として評価されます。制限として、それぞれのバインディングは、単一の式だけ含むことができるというものです。なので、以下は動作しません:

<!-- これは文であり、式ではありません: -->
{{ var a = 1 }}
<!-- フロー制御もいずれも動作しません。三項演算子を使用してください -->
{{ if (ok) { return message } }}

テンプレート式はサンドボックスで、MathDate といったホワイトリストにあるグローバルオブジェクトだけアクセスできます。テンプレート式内でユーザーが定義したグローバルオブジェクトにアクセスしようとしてはいけません。

ディレクティブ

ディレクティブは v- から始まる特別な属性です。ディレクティブ属性値は、単一の JavaScript 式を期待します(ただし、v-forは例外で、これについては後から説明します)。ディレクティブの仕事は、属性値の式が変化したときに、リアクティブに副作用を DOM に適用することです。イントロダクションで見た例を振り返ってみましょう:

<p v-if="seen">Now you see me</p>

ここでの v-if ディレクティブは seen 式の値が真か否かに基づいて、 <p> 要素を削除/挿入します。

引数

ディレクティブの中には “引数” を取るものもあります。これはディレクティブ名の後にコロンで表記します。例えば、v-bindディレクティブは、リアクティブに HTML 属性を更新します:

<a v-bind:href="url"></a>

ここでの hrefv-bind ディレクティブに要素の href 属性に式 url の値を束縛することを教えるための引数です。

v-on ディレクティブの別の例を見てみましょう。これは DOM イベントを受け取ります:

<a v-on:click="doSomething">

ここでの引数は受け取りたいイベント名です。ここからイベントハンドリングの詳細について説明します。

修飾子

修飾子 (Modifier) は、ドットで表記された特別な接尾語で、ディレクティブが特別な方法で束縛されるべきということを示します。例えば、.prevent 修飾子は v-on ディレクティブに、イベントがトリガーされた際 event.preventDefault() を呼ぶように伝えます:

<form v-on:submit.prevent="onSubmit"></form>

この後、v-onv-model を詳しく見ていく中で、さらに多くの修飾子が登場します。

フィルタ

Vue.js では、一般的なテキストフォーマットを適用するために使用できるフィルタを定義できます。フィルタは、mustache 展開と v-bind、2 つの場所で使用できます。フィルタは JavaScript 式の末尾に追加する必要があります。これは “パイプ(‘|’)” 記号で表されます。

{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>

Vue 2.x フィルタは、mustache バインディングと v-bind 式 (2.1.0 以降のサポート)でだけ使用できます。同じ振る舞いをディレクティブのバインディング内部で実現するには、代わりに算出プロパティを使用すべきです。

フィルタ関数は常に式の値(前のチェーンの結果)を第一引数として受け取ります。この例では、 capitalize フィルタ関数は引数として message の値を受け取ります。

new Vue({
// ...
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})

フィルタは連結できます:

{{ message | filterA | filterB }}

この場合、単一の引数で定義された filterAmessage の値を受け取り、filterBの単一引数に filterA の結果を渡して filterB 関数が呼び出されます。

フィルタは JavaScript 関数なので、引数を取ります:

{{ message | filterA('arg1', arg2) }}

ここで filterA は3つの引数をとる関数として定義されています。message の値は最初の引数に渡されます。プレーン文字列 'arg1' は、第2引数として filterA に渡されます。そして、式 arg2 の値が評価され、第3引数としてフィルタに渡されます。

省略記法

v- 接頭子は、テンプレート内の Vue 独自の属性を識別するための目印となっています。これは既存のマークアップに対して、 Vue.js を利用して動的な振る舞いを適用する場合に便利ですが、頻繁に利用されるディレクティブに対しては冗長に感じることがあるでしょう。同時にシングルページアプリケーションを作成するにあたり、全てのテンプレートを Vue.js で管理しているとき、v- 接頭子を付ける必要性は低いものになるでしょう。したがって、 Vue.js は 2 つの最もよく使われるディレクティブ v-bindv-on に対して特別な省略記法を提供しています:

v-bind 省略記法

<!-- 完全な構文 -->
<a v-bind:href="url"></a>
<!-- 省略記法 -->
<a :href="url"></a>

v-on 省略記法

<!-- 完全な構文 -->
<a v-on:click="doSomething"></a>
<!-- 省略記法 -->
<a @click="doSomething"></a>

これらは普通の HTML とはちょっと違うように見えるかもしれません。ですが、 :@ は属性名に利用可能な文字です。すべての Vue.js のサポートしているブラウザで、正しくパースすることができます。加えて、最終的に描画されるマークアップにそれらは現れません。省略記法の構文の利用は完全に任意ですが、後でその使用方法について詳しく学んだ時に便利と感じることでしょう。