v3.x のドキュメントを見たい場合はこちら

v2.x 以前のドキュメントです。 v3.x のドキュメントを見たい場合はこちら

テンプレート構文

最終更新日: 2020年9月4日

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 ディレクティブを使用する必要があります:

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

Using mustaches: {{ rawHtml }}

Using v-html directive:

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

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

属性

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

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

属性が単に存在していることを true と示すといった真偽値属性の場合、v-bind は少し異なった働きをします。この例では:

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

isButtonDisablednullundefined、または false の値を持つ場合、disabled 属性は描画された <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"> ... </a>

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

動的引数

2.6.0 から新規

バージョン 2.6.0 から、角括弧で囲むことで JavaScript 式をディレクティブの引数に使うこともできます:

<!--
動的引数には、"動的引数の式の制約" の節で後述されるように、いくつかの制約がある点に注意してください。
-->
<a v-bind:[attributeName]="url"> ... </a>

ここで attributeName は JavaScript 式として動的に評価され、その評価結果が引数の最終的な値として使われます。例えば、Vue インスタンスが "href" という値の attributeName という data プロパティをもつ場合、このバインディングは v-bind:href と等しくなります。

同様に、動的なイベント名にハンドラをバインドするために動的引数を使うこともできます:

<a v-on:[eventName]="doSomething"> ... </a>

この例では、eventName の値が "focus" だとすると、v-on:[eventName]v-on:focus と等しくなります。

動的引数の値の制約

動的引数は、null を除くと string に評価されることが想定されています。特殊値 null は、明示的にバインディングを削除するのに使われます。その他の string 以外の値は、警告を引き起こします。

動的引数の式の制約

動的引数の式には構文上の制約があります。というのも、スペースや引用符のような一部の文字は、HTML の属性名としては不正な文字だからです。例えば、以下は不正です:

<!-- これはコンパイラ警告を引き起こします -->
<a v-bind:['foo' + bar]="value"> ... </a>

回避策は、スペースや引用符を含まない式を使うか、複雑な式を算出プロパティで置き換えるかです。

in-DOM テンプレート (すなわち、HTML ファイルに直接書かれるテンプレート) を使う場合、ブラウザが強制的に属性名を小文字にするため、キー名を大文字にするのは避けるべきです:

<!--
in-DOM テンプレートの中では、v-bind:[someattr] に変換されます。
インスタンスに "someattr" プロパティがない場合、このコードは動作しません。
-->
<a v-bind:[someAttr]="value"> ... </a>

修飾子

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

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

後ほどv-onおよびv-modelの説明をする際、修飾子の他の例を見るでしょう。

省略記法

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

v-bind 省略記法

<!-- 完全な構文 -->
<a v-bind:href="url"> ... </a>

<!-- 省略記法 -->
<a :href="url"> ... </a>

<!-- 動的引数の省略記法 (2.6.0 以降) -->
<a :[key]="url"> ... </a>

v-on 省略記法

<!-- 完全な構文 -->
<a v-on:click="doSomething"> ... </a>

<!-- 省略記法 -->
<a @click="doSomething"> ... </a>

<!-- 動的引数の省略記法 (2.6.0 以降) -->
<a @[event]="doSomething"> ... </a>

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