基礎からメモ: Vue.js CH2-p62 クラスとスタイルのデータバインディング
クラスやスタイルの適用
v-bind
を使って、HTMLにクラスやスタイルを適用できる。Vueインスタンスのデータ側に、クラスの適用可否やスタイルの内容を設定しておけば、データ側の変更によってクラスやスタイルの変更ができる。
[index06.html]
<p v-bind:class="{ child: isChild, 'is-active': isActive }">Text</p> <p v-bind:style="{ color: textColor, backgroundColor: bgColor }">Text</p>
[main06.js]
var app = new Vue({ el: '#app', data: { isChild: true, isActive: true, textColor: 'red', bgColor: 'lightgray', }, })
出力されるHTML
Text
Text
<p class="child is-active">Text</p> <p style="color: red; background-color: lightgray;">Text</p>
HTML側でのクラス名を、キャメルケースのクラス名はそのままで、ハイフンを含む場合だけクオートで囲っている。これを忘れると次のようなエラーになる。
- invalid expression: Unexpected token - in { child: isChild, is-active: isActive }
これはVue.jsの仕様なので忘れないようにする。
プレーンな属性との併記
データバインディングされていない普通の属性がHTML側にある場合、クラス名はマージされ、スタイルセレクターが重なるとVueインスタンスの出力で上書きされたうえでマージされる。結果、プレーンなCSS指定は無視される。
<p class="child" v-bind:class='{ "is-active": isActive }'>Text</p> <p style="color:green" v-bind:style="{ color: textColor }">Text</p>
出力されるHTML
<p class="child is-active">Text</p> <p style="color: red;">Text</p>
ただクラス名が重なる場合、マージされてもプレーンなクラス名は消えず同じクラス名が複数残るので注意。
<p class="child" v-bind:class='{ child: isChild, "is-active": isActive }'>Text</p>
出力されるHTML
<p class="child child is-active">Text</p>
クラス名展開に配列や三項演算子を使用
v-bind
でバインドしたクラス名を示す変数がデータ上で配列であれば、展開されて複数のクラス名になる。また三項演算子でクラス名の選択をすることも可能。
<p v-bind:class="[isActive ? 'active' : 'normal', otherClass]">Text</p>
この場合app.isActive
がtrue
ならactive
が、false
ならnormal
が選ばれる。またapp.otherClass
がotherClass: ['classA', 'classB', 'classC']
といった感じで配列になっていると展開されて例えば次のような形になる。
<p class="active classA classB classC">Text</p>
ただし属性に三項演算子を使うのは冗長なので、次のようにオブジェクトデータを使うか、算出プロパティを使うのが良いとのこと。
属性にオブジェクトを渡す
複数のクラスやスタイルを直接HTMLの属性に書くと見にくくなるので、そういうときはdata
オプションにオブジェクトで定義し、HTML側にはオブジェクト名で渡す。
<p v-bind:class="classObject">Text</p> <p v-bind:style="styleObject">Text</p>
// クラスとスタイルのオブジェクト classObject: { child: true, 'is-child': true, 'is-active': false }, styleObject: { color: 'blue', backgroundColor: 'lavender' }
この場合、値がtrue
のchild
とis-child
は反映されるが、is-active
はfalse
なので反映されない。
結果のHTML
<p class="child is-child">Text</p> <p style="color: blue; background-color: lavender;">Text</p>
この方法は当然クラスやスタイル以外の属性データにも使える。たくさんのプロパティをバインドしたいときは、一つひとつ書かずにオブジェクトにまとめて渡すとすっきりする。また次のような引数付きのv-bind
を使うと特定の要素をアレンジできる。
<p><img v-bind="item" v-bind:id="'thumb-' + item.id"></p>
// オブジェクトデータ item: { id: 1, src: "item1.jpg", alt: "商品1サムネイル", width: 200, height: 200 }
結果のHTML
<p> <img id="thumb-1" src="item1.jpg" alt="商品1サムネイル" width="200" height="200"> </p>
- v-bindを使って、HTMLにクラスやスタイルを適用できる。
- プレーンな属性との併記では、上書きされマージされる。
- クラス名展開に配列や三項演算子が使用できる。データ側で配列で定義されたクラス名は複数のクラスに展開される。
- 複数の属性を直接HTMLに書くときは、dataオプションにオブジェクトで定義しHTML側にはオブジェクト名で渡す。