Vue.jsのv-bindディレクティブを使用することで、HTMLタグの中のclass属性やstyle属性を動的、あるいは静的に適用することができます。
Vue.js側でスタイルの適用のオン・オフを切り替える設定(動的な設定)や、Vue.js側に設定してある値を属性名を適用する設定(静的な設定)が可能です。
ここでは、v-bindを使ってclassやstyle属性を変更する方法について実例で解説しています。
使用するCSSファイル
v-bindの使い方を理解しやすくするために、例としてCSSファイルに以下の4つのスタイルを用意し、それぞれを静的あるいは動的にHTMLに適用しながら解説します。
.large{
font-size: 36px;
}
.redCollor{
color: red;
}
.under-line{
text-decoration: underline;
}
.bg-color{
background-color: beige;
}
用意するスタイルは、大文字設定にするlarge, 赤色にするredCollor, 下線を引くunder-line, 背景色をベージュ色にするbg-colorの4つです。
静的な値を適用する方法
記述方法
Vue.jsにあるCSSスタイル名を、v-bindを使ってHTML上のclsss属性に適用する方法場合は、以下のように記述します。
v-bind:class="プロパティ名"
v-bindの省略形
v-bindには省略した書き方もあります。「v-bind:」の「v-bind」の部分を省略しても、まったく同じ動作になります。
v-bind:class="プロパティ名"
以下と同じです。
:class="プロパティ名"
実際の現場ではv-bindが省略されるのが普通です。
この記事では見やすさ重視のため、あえてv-bindをつけた記述を使用しています。
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//静的な適用
largeClass: 'large',
bgColorClass: 'bg-color',
redClass: 'redCollor',
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="largeClass">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="largeClass">
により、このpタグのclass属性に、Vue.jsのlargeClassの値「large」が入ります。
これによりCSSの.large{ font-size: 36px; }
が適用されます。
ブラウザの表示
HTMLのソースコードは次のようになっています。
<p class="large">
test
</p>
複数指定する方法
v-bindで属性名を複数指定する場合は配列で指定します。
v-bind:class="[プロパティ名1,プロパティ名2,,,]"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//静的な適用
largeClass: 'large',
bgColorClass: 'bg-color',
redClass: 'redCollor',
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="[largeClass, bgColorClass, redClass]">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="[largeClass, bgColorClass, redClass]">
により、このpタグのclass属性に、Vue.jsのlargeClassの値「large」、 bgColorClassの値「bg-color」、redClassの値「redCollor」が入ります。
ブラウザの表示
指定した要素に3つのスタイルが全て適用されていることがわかります。
動的にスタイルを適用する
Vue.jsのデータで値に真偽値を持つプロパティを使うと、適用するクラスを真偽値の値に合わせて動的に切り替えることができます。
例えば、選択しているときは赤枠で囲み、選択を解除するとスタイルを外すといったように、「~ならスタイルを適用する」といった切り分けに使用します。
適用方法は次のように、class属性にv-bind適用し、適用したいクラス名を記述し、コロンの後ろにプロパティ名を記述します。
v-bind:class="{クラス名: プロパティ名}"
実際にスタイルの適用を切り替えるときは、Vue.jsのプロパティの値を、watchやmethodなどの処理によって変更する処理をします。
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//動的な適用
isLarge: true,
isRed: 0,
isUnderLine: 'xxx'
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="{large: isLarge}">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="{large: isLarge}">
により、isLargeの値がtrueの場合は、class=”large”になります。
isLargeの値がfalseの場合は、class=””(largeは適用されない状態)になります。
複数指定する場合
スタイルを動的に複数指定する場合は、クラス名: プロパティ名
のセットをカンマでつなぎます。
その際、適用するセレクタ名にハイフンを含む場合はシングルクオーテーションをつける必要があります。
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//動的な適用
isLarge: true,
isRed: 0,
isUnderLine: 'xxx',
isBgColor: ""
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="{ large: isLarge, redColor: isRed, 'under-line':isUnderLine, 'bg-color': isBgColor }">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="{ large: isLarge, redColor: isRed, 'under-line':isUnderLine, 'bg-color': isBgColor }">
とすることで、4つのスタイルをプロパティの値によってつけ分けています。
under-lineとbg-colorはハイフンを含むため、シングルクオーテーションで囲んでいることに注意してください(囲まないとエラーになります)。
Vue.jsでisRed: 0
, isBgColor: ""
としているため、値はfalse扱いとなり、この2つのスタイルは適用されません。
ブラウザの表示
ソースコードをみると、プロパティの値がtrue判定となる、largeとunder-lineのみが適用されていることがわかります。
<p class="large under-line">
test
</p>
動的と静的を同時に適用する
v-bindで動的に適用するクラス名と、静的な値として適用するクラス名を同時に適用することもできます。
同時に適用する場合は、配列で記述します。
v-bind:class="[プロパティ名, {クラス名: プロパティ名}]"
複数の場合は以下のようになります。
v-bind:class="[プロパティ名1, プロパティ名2,,,, {クラス名3: プロパティ名3, クラス名4: プロパティ名4,,,} ]"
同不順です。
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//動的な適用
isLarge: true,
isRed: 0,
isUnderLine: 'xxx',
isBgColor: "",
//静的な適用
largeClass: 'large',
bgColorClass: 'bg-color',
redClass: 'redCollor',
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="[{ large: isLarge, 'under-line':isUnderLine}, bgColorClass, redClass]">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="[{ large: isLarge, 'under-line':isUnderLine}, bgColorClass, redClass]">
で4つのスタイルを適用しています。
largeとunder-lineは真偽値判定で動的に出し分け、bgColorClassとredClassは値を適用しています。
ブラウザの表示
v-bindしていないclass属性との併用方法
v-bindしていない通常のクラスと合わせて、v-bindしたクラスを適用することもできます。
v-bindでプロパティの値がクラス名になっているデータと合わせて適用する場合は以下のようになります。
class="クラス名" v-bind:class="プロパティ名"
複数の場合は配列にします。
class="クラス名" v-bind:class="[プロパティ名1, プロパティ名2,,,]"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//静的な適用
largeClass: 'large',
bgColorClass: 'bg-color',
redClass: 'redCollor',
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p class="large" v-bind:class="[bgColorClass, redClass]">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p class="large" v-bind:class="[bgColorClass, redClass]">
で3つのスタイルを適用しています。
ブラウザの表示
ブラウザに表示するときには、通常のclassもv-bindでつなげたclassもひとまとまりのclassにコンパイルされて出力されます。
<p class="large bg-color redCollor">
test
</p>
v-bindの動的なクラスとの併用
v-bindで動的なクラスと通常のclassを適用する場合は次のようになります。
class="クラス名" v-bind:class="{クラス名: プロパティ名}"
複数の場合は配列にします。
class="クラス名" v-bind:class="{クラス名1: プロパティ名1, クラス名2: プロパティ名2,,,}"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//動的な適用
isLarge: true,
isRed: 0,
isUnderLine: 'xxx',
isBgColor: ""
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p class="large redCollor" v-bind:class="{'under-line':isUnderLine, 'bg-color': isBgColor}">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p class="large redCollor" v-bind:class="{'under-line':isUnderLine, 'bg-color': isBgColor}">
で4つのスタイルを適用しています。
通常のclass属性のセレクタで指定しているのがlargeとredCollor、v-bindで動的に出し分けているのがunder-lineとbg-colorの2つです。
ブラウザの表示
isBgColor: ""
のため、false判定となり背景色のスタイルは適用されません。
<p class="large redCollor under-line">
test
</p>
複数のスタイルをまとめて適用する(オブジェクトデータによる適用)
Vue.js側のデータをオブジェクト形式にすると、複数のデータをまとめて渡すことができいます。
v-bind:class="オブジェクト名"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
//オブジェクトデータでの適用(cssのセレクタを記述)
classObject:{
large: true,
redCollor: false,
'bg-color': true, //ハイフンを含む時はシングルクオテーションで囲む
'under-line': 1
}
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="classObject">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="classObject">
でVue側に設定してあるclassObjectの中身をまとめて適用しています。
redCollor: false
なので .redCollor{ color: red; }
は適用されません。
ブラウザの表示
コンパイル後のソースコードは以下のようになっています。
<p class="large bg-color under-line">
test
</p>
三項演算子を使った適用
if文の省略形である三項演算子を使って条件分岐によって適用するクラスを切り分けることもできます。
v-bind:class="プロパティ名 ? trueで適用するプロパティ名 : falseで適用するプロパティ名"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
isLarge: true,
LargeClass: 'large',
bgColorClass: 'bg-color'
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:class="isLarge ? LargeClass : bgColorClass">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:class="isLarge ? LargeClass : bgColorClass">
でどのスタイルを適用するかを判定しています。
isLargeの判定結果がtrueの場合、LargeClassプロパティの値が適用されます。 isLargeの判定結果がfalseの場合、bgColorClassプロパティの値が適用されます。
ブラウザの表示
コンパイル後のソースコードは以下のようになっています。
<p class="large">
test
</p>
インラインスタイルで適用(style属性への適用)
v-bindが使えるのはclass属性だけではありません。タグのあらゆる属性に対して使用することができます。
このため、style属性に対してv-bindを使ってスタイルを適用することもできます。
なおインラインスタイルとは、<タグ名 style="セレクタ: プロパティ">
という記述で、HTMLのタグに直接CSSを適用する方法です。
<div style="color: red">
適用方法
v-bind:style="{CSSのプロパティ名: Vueのプロパティ名}"
複数適用する場合はカンマでつなぎます。
v-bind:style="{CSSのプロパティ名: Vueのプロパティ名, CSSのプロパティ名: Vueのプロパティ名,,,,}"
注意点
CSSのプロパティがハイフンを含む場合
例えば、font-size
の場合は、次のようにシングルクオーテーションで囲むか、キャメル(2文字目以降の冒頭頭文字)にします。
プロパティ名に追加文字が必要な場合
例えば、スタイルのプロパティの値に24pxを適用する場合に、Vue側のプロパティの値が24となっている場合は、v-bindしたときに「+」で文字列を追加します。
v-bind:style="{ fontSize: Vueのプロパティ名 + 'px' }"
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
isLarge: true,
//インラインスタイルに適用する
colorBlue:"blue",
textSize:24,
textBold: "bold"
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:style="{color: colorBlue, 'font-size': textSize + 'px', fontWeight: textBold }">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
<p v-bind:style="{ color: colorBlue, 'font-size': textSize + 'px', fontWeight: textBold }">
で3つのスタイルを適用しています。
ブラウザの表示
コンパイル後のソースコードは次のようになります。
<p style="color: blue; font-size: 24px; font-weight: bold;">
test
</p>
インラインスタイルをまとめて適用する方法
Vue側のデータをオブジェクト形式にすると、インラインスタイルをまとめて適用することができます。
data: {
styleObject:{
CSSプロパティ名1: 値1,
CSSプロパティ名2: 値2,
,,,,
}
}
実例
Vue.js
var app = new Vue({
el:"#app",
data: {
styleObject:{
color:"blue",
fontSize:"36px",
textDecoration: 'underline'
}
}
})
HTML
<body>
<div id="app">
<p>▼CSSを適用</p>
<p v-bind:style="styleObject">
test
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
</body>
ブラウザの表示
コンパイル後のソースコードは次のようになります。
<p style="color: blue; font-size: 36px; text-decoration: underline;">
test
</p>
確認用ソースコード
参考までに、上記のスタイルの適用をまとめて確認に加え、ボタンクリックでスタイルの適用・非適用を切り替えられるコードを載せておきます。自分のVue.js環境であれこれいじり倒してみてください。
ブラウザの表示
ボタンクリックで真偽値を切り替え、スタイルを変更させる機能を実装。
Vue.jsのコード(.jsファイル用)
var app = new Vue({
el:"#app",
data: {
//動的な適用
isLarge: true,
isRed: true,
isUnderLine: true,
isBgBeige: true,
//静的な適用
LargeClass: 'large',
bgColorClass: 'bg-color',
redClass: 'redCollor',
//オブジェクトデータでの適用(cssのセレクタを記述)
classObject:{
large: true,
redCollor: true,
'bg-color': true
},
//インラインスタイルでの適用
colorBlue:"blue",
textSize:24,
//オブジェクトデータをインラインスタイルで適用
styleObject:{
color:"blue",
fontSize:"24px",
}
},
methods:{
isLargeToggle: function(){
this.isLarge == true ? this.isLarge = false : this.isLarge = true
},
isRedToggle: function(){
this.isRed == true ? this.isRed = false : this.isRed = true
}
}
})
HTMLファイルのコード(.html用)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>class, style binding</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="app">
<div>・静的に適用(通常のCSS)
<p>
apply <span class="large">statically</span>
</p>
</div>
<hr>
<div>・動的に適用(真偽値)
<p>
apply <span v-bind:class="{large: isLarge}">dynamically</span><br>
apply <span v-bind:class="{large: isLarge, redCollor: isRed, 'under-line':isUnderLine}">multi style dynamically</span>
<br>
<br>
<button v-on:click="isLargeToggle">isLarge</button>
<button v-on:click="isRedToggle">isRed</button>
</p>
</div>
<hr>
<div>・静的と動的の共存
<p>
apply <span class="redCollor under-line" v-bind:class="{large: isLarge, 'bg-color':isBgBeige}">dynamically</span><br>
</p>
</div>
<hr>
<div>・静的に適用(v-bind 単体 & 配列構文による適用)
<p>
apply <span v-bind:class="bgColorClass">v-bind data property</span><br>
apply <span v-bind:class="[redClass, LargeClass]">v-bind multi data properties</span><br>
</p>
</div>
<br>
<hr>
<div>・オブジェクトデータによる適用(ひとまとめの設定をv-bindで渡す)
<p>
apply <span v-bind:class="classObject">v-bind classオブジェクト</span>
</p>
</div>
<hr>
<div>・三項演算子を使った適用
<p>
apply <span v-bind:class="isLarge? LargeClass : bgColorClass">三項演算子による適用</span>
<br><button v-on:click="isLargeToggle">isLarge</button>
</p>
</div>
<hr>
<div>・インラインスタイルで適用(v-bind:style="{}")
<p>
apply <span v-bind:style="{color: colorBlue, 'font-size': textSize + 'px' }">inline-style</span>
</p>
</div>
<hr>
<div>・オブジェクトデータをインラインスタイルで適用(v-bind:style="")
<p>
apply <span v-bind:style="styleObject">inline-style</span>
</p>
</div>
<hr>
<div>
<pre>{{$data}}</pre>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="js/script.js"></script>
</body>
</html>
CSSファイルのコード
.large{
font-size: 36px;
}
.redCollor{
color: red;
}
.under-line{
text-decoration: underline;
}
.bg-color{
background-color: beige;
}
以上です。