前 Vue.js入門 2章 Vue.jsの入門(テンプレート、フィルタ、算出プロパティ)
次 Vue.js入門 2章 Vue.jsの入門(ライフサイクルフック/メソッド)
ディレクティブ
- 標準のHTMLに対して独自の属性を追加することで、属性値の式の変化に応じたDOM操作を行う。この特別な属性をディレクティブと言う。
- Vueインスタンスをマウントした要素と、その子孫でしか使えない。
- ディレクティブの属性値には、JavaScriptの式を与える。データや算出プロパティも使える。
条件付きレンダリング(v-if/v-show)
- テンプレート中の要素の表示・非表示を切り替えるのに、v-ifまたはv-showディレクティブを使う。
- いずれも、真の場合は表示、偽の場合は非表示にする。
- 頻繁に式の評価結果が変わる場合は、v-showを使う。
<p v-show="引数">
// 真の場合は表示、偽の場合は非表示
</p>
- ほとんど変わらない場合は、v-ifを使う。
<p v-if="引数">
// 真の場合は表示、偽の場合は非表示
</p>
サンプルアプリケーションでの実装
-
v-show
に!canBuyを引数として入れる。
<p v-show="!canBuy">
{{ 1000 | numberWithDelimiter }}円以上からご購入いただけます
</p>
- 算出プロパティに、
canBuy
を追加する。
computed: {
canBuy: function () {
return this.totalPrice >= 1000 // 1000円以上から購入可能にする
}
}
- 1000円未満の時
- consoleから100個に変更で、「1000円以上から購入いただけます」が消えたことを確認。
クラスとスタイルのバインディング
- v-bindはクラスやスタイルを買いたいときに使われるディレクティブ。
v-bind:属性名="データを展開した属性値"
v-bind:class="オブジェクト・配列"
v-bind:style="オブジェクト・配列"
クラスのバインディング(v-bind:class)
- trueのプロパティ名がclass名になる。以下は、sharkがclass名になる。
<p v-bind:class="{shark: true, mecha: false}"></p>
- canBuyがfalseの時、class名はerrorになる。
<p v-bind:class="{error: !canBuy}">1000円以上から購入いただけます</p>
- 算出プロパティを使った例。上記と同じようにcanBuyがfalseの時、class名はerrorになる。
computed: {
errorMessageClass: function () {
return {
error: !this.canBuy
}
}
}
<p v-bind:class="errorMessageClass">1000円以上から購入いただけます</p>
スタイルのバインディング(v-bind:style)
- オブジェクトのプロパティがスタイルのプロパティに対応する。
<p v-bind:style="{color: red}">a</p>
↓
<p style="color: red;">a</p>
- 式と組み合わせて使うことができる。
<p v-bind:style="{border: (canBuy ? '' : '1px solid red'), color: (canBuy ? '' : 'red')}">
1000円以上から購入いただけます
</p>
- 算出プロパティを使った例。
computed: {
errorMessageStyle: function () {
return {
border: this.canBuy ? '' : '1px solid red',
color: this.canBuy ? '' : 'red'
}
}
}
<p v-bind:style="errorMessageStyle">1000円以上から購入いただけます</p>
v-bindの省略記法
- 「v-bind:属性名」の省略記法は「:属性名」。コロンを属性値につけるだけ。
<p :class="{error: !canBuy}">1000円以上から購入いただけます</p>
スタイルのバインディングのサンプルへの適用
- スタイルのバインディング
<script src="https://unpkg.com/vue@2.5.17"></script>
<div id="app">
<!-- 1000円以上になるまで、赤く表示する -->
<div :style="errorMessageStyle">
<p>{{ items[0].name }}: {{ items[0].price }} x {{ items[0].quantity }}</p>
<p>小計: {{ totalPrice | numberWithDelimiter }}円</p>
<p>合計(税込): {{ totalPriceWithTax | numberWithDelimiter }}円</p>
<p v-show="!canBuy">
{{ 1000 | numberWithDelimiter }}円以上からご購入いただけます
</p>
</div>
</div>
- 算出プロパティの追加部分。
errorMessageStyle: function () {
// canBuyが偽の時に赤く表示する
return {
border: this.canBuy ? '' : '1px solid red',
color: this.canBuy ? '' : 'red'
}
}
}
- 1000円に満たない時
- コンソールで個数を100個に変更
リストレンダリング(v-for)
- v-forディレクティブで、配列あるいはオブジェクトのデータをリストレンダリングできる。
-
v-for="要素 in 配列"
のように書く。 - v-bind:key="・・・"で、生成時に一意なキーを各要素に与える必要がある。
<!-- data: { arr: [ 'い', 'ろ', 'は']} -->
<ul>
<li v-for="item in arr" v-bind.key="item">{{ item }}</li>
</ul>
インデックスあり
<ul>
<li v-for="(item,index) in arr" v-bind.key="item">{{ index }}{{ item }}</li>
</ul>
サンプルアプリケーションでの実装
- 以下のように、v-forで、リスト表示する。
<ul>
<!-- 各商品の単価と購入個数をリスト表示する -->
<li v-for="item in items" v-bind:key="item.name">
{{ item.name }}: {{ item.price }} x {{ item.quantity }} = {{ item.price * item.quantity | numberWithDelimiter }}円
</li>
</ul>
- 1000円に満たない時
- コンソールで個数を100個に変更
イベントハンドリング(v-on)
- v-onディレクティブは、イベントが起きた時に属性値の式を実行する。
-
v-on:イベント名="式として実行したい属性値"
で定義する。
<li v-for="item in items" v-bind:key="item.name">
<!-- v-onでイベントが発生した時に属性値で指定した式を評価する -->
{{ item.name }}の個数: <input type="number" v-on:input="item.quantity = $event.target.value" v-bind:value="item.quantity" min="0">
</li>
- v-onは、@で置き換えることができる。
<input type="number" @input="item.quantity = $event.target.value" :value="item.quantity" min="0">
フォーム入力バインディング(v-model)
- v-on:input、v-bind:valueを記述するのは骨の折れる作業。
- v-modelディレクティブを使えば、双方データバインディングが実現できる。
- ビューで変更があった場合はデータを更新し、データが変更があった場合はビューを再レンダリングする。
<input type="number" v-model="item.quantity" min="0">
-
v-model.lazy
のように、修飾子を付けることにより動作を変えられる。(lazyはchangeイベントで、inputのフォーカスから外れた時)