Vue入門8 v-bindディレクティブでCSSを動的に指定

Vue入門の第8回(第1回はこちら)です。今回は、v-bindディレクティブを使ってCSSの値を動的に指定します。

CSSの値を動的に指定したい

以下は、前回までに作成したサンプルページです。

https://programming-world.net/sample/vue_sample/07/index.html

上記のサンプルページでは、「ピンク」「ブルー」と表示された靴下の色名のテキストをクリックした際に、靴下画像の表示が切り替わるようになっています。この表示切替を見やすくするために、CSSを使って表示スタイルを変更しようと思います。

今回、作成するのは、以下のサンプルページです。

https://programming-world.net/sample/vue_sample/08/index.html

上記のサンプルページを作成する際に、CSSを動的に切り替えられると便利なのですが、Vueのv-bindディレクティブを使えば簡単に実現できます。

では、今回の作成を始めましょう。

index.htmlを書き換える

前回作成したHTMLファイル index.html を以下のように書き換えます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Vueサンプル</title>
    <script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
	<div class="item">

		<div class="item-image">
		    <img v-bind:src="itemImage" />
		</div>

		<div class="item-info">
		    <h2>{{ itemName }}</h2>
		    <ul><li v-for="itemInfo in itemInfos">{{ itemInfo }}</li></ul>
		    <p v-if="zaiko > 2">在庫あり</p>
		    <p v-else-if="zaiko <= 2 && zaiko > 0">残りわずか!</p>
		    <p v-else>在庫なし</p>

		    <div 
		    v-for="itemColor in itemColors" 
		    v-on:click="changeColor(itemColor.cImage)" 
		    v-bind:style="{ backgroundColor: itemColor.cCode }" 
		    style="width:30px; height:30px; margin-bottom:20px;"
		    >
		    </div>

		    <button v-on:click="addCart">買い物かごの中身を増やす</button>
		    <div class="cart">
		        <p>買い物かごの中身 {{ cart }}</p>
		    </div>
		</div>

	</div>
</div>
<script src="main.js"></script>
</body>
</html>

このindex.htmlの書き換えでは、まず style=”width:30px; height:30px; margin-bottom:20px;”の部分を追加しています。この部分ではCSSをベタ打ちして、div要素にstyle属性を追加してスタイルを指定しています。div要素のスタイルを幅30ピクセル×高さ30ピクセル、下マージンが20ピクセルにしなさいと指定しています。

このindex.htmlの書き換えでは、 v-bind:style=”{ backgroundColor: itemColor.cCode }” の部分も追加されています。この部分では、第2回で学んだv-bindディレクティブを使って、HTMLコードのdiv要素のstyle属性とVueコードを結びつけています。この部分では、背景色のカラーコードをVue側で動的に指定しようとしています。

main.jsを書き換える

次に、前回作成したJSファイル main.js を以下のように書き換えます。

var app = new Vue({
    el: '#app',
    data: {
        itemName: 'キッズ靴下',
        itemImage: './images/socks-pink.png',
        itemInfos: ["子供向け靴下", "コットン100%", "人気商品!"],
        itemColors: [
            {cName:"ピンク", cCode:"#ee6699", cImage:"./images/socks-pink.png"},
            {cName:"ブルー", cCode:"#33aaee", cImage:"./images/socks-blue.png"}
        ],
        zaiko: 5,
        cart: 0
    },
    methods: {
        addCart: function () {
            this.cart += 1
        },
        changeColor (cImage) {
            this.itemImage = cImage
        }
    }
})

このmain.jsの書き換えでは、dataプロパティのなかの itemColors: [ ~ ]の部分で、 ピンクのカラーコードの値cCode:”#ee6699″、および ブルーのカラーコードの値cCode:”#33aaee”を追加しています。

表示を確認してみる

ここまで出来たら、 index.htmlとmain.jsを上書き保存して表示を確認してみましょう。以下は、今回作成したサンプルページです。

https://programming-world.net/sample/vue_sample/08/index.html

ピンクとブルーのカラーボックスが表示されて、そのカラーボックスをクリックした際に靴下画像の表示が切り替われば成功です。

VueでCSS(スタイルシート)を指定する

index.htmlに追加した以下の部分では、第2回で学んだv-bindディレクティブを使って、HTMLコードのdiv要素のstyle属性とVueコードを結びつけています。

<div 
v-for="itemColor in itemColors" 
v-on:click="changeColor(itemColor.cImage)" 
v-bind:style="{ backgroundColor: itemColor.cCode }" 
style="width:30px; height:30px; margin-bottom:20px;"
>
</div>

CSSで背景色を指定するには「background-color」プロパティを使用しますが、上記コード例で指定されているのは「backgroundColor」というスタイルオブジェクト名です。

もし、CSSのプロパティ名に慣れているなら、以下のようにクォーテーションで囲んで記述することで、CSSのプロパティ名でスタイルを指定することもできます。

v-bind:style="{ 'background-color': itemColor.cCode }" 

イベントが発生したら、メソッドを呼び出す

backgroundColor: itemColor.cCodeの部分で指定している「itemColor.cCode」の値は、 main.js側で用意します。

以下のコードでは、「cCode:”#ee6699″」と「cCode:”#33aaee”」の部分が追加されています。

itemColors: [
    {cName:"ピンク", cCode:"#ee6699", cImage:"./images/socks-pink.png"},
    {cName:"ブルー", cCode:"#33aaee", cImage:"./images/socks-blue.png"}
],

ここで指定したカラーコードは、今回index.htmlに追加した「backgroundColor: itemColor.cCode」の部分で利用されます。

HTMLコードとVueコードを通して確認

最後にもう一度、HTMLコードとVueコードを通して確認しておきましょう。

現在の index.html は、以下の通りです。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Vueサンプル</title>
    <script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
	<div class="item">

		<div class="item-image">
		    <img v-bind:src="itemImage" />
		</div>

		<div class="item-info">
		    <h2>{{ itemName }}</h2>
		    <ul><li v-for="itemInfo in itemInfos">{{ itemInfo }}</li></ul>
		    <p v-if="zaiko > 2">在庫あり</p>
		    <p v-else-if="zaiko <= 2 && zaiko > 0">残りわずか!</p>
		    <p v-else>在庫なし</p>

		    <div 
		    v-for="itemColor in itemColors" 
		    v-on:click="changeColor(itemColor.cImage)" 
		    v-bind:style="{ backgroundColor: itemColor.cCode }" 
		    style="width:30px; height:30px; margin-bottom:20px;"
		    >
		    </div>

		    <button v-on:click="addCart">買い物かごの中身を増やす</button>
		    <div class="cart">
		        <p>買い物かごの中身 {{ cart }}</p>
		    </div>
		</div>

	</div>
</div>
<script src="main.js"></script>
</body>
</html>

現在の main.js は、以下の通りです。

var app = new Vue({
    el: '#app',
    data: {
        itemName: 'キッズ靴下',
        itemImage: './images/socks-pink.png',
        itemInfos: ["子供向け靴下", "コットン100%", "人気商品!"],
        itemColors: [
            {cName:"ピンク", cCode:"#ee6699", cImage:"./images/socks-pink.png"},
            {cName:"ブルー", cCode:"#33aaee", cImage:"./images/socks-blue.png"}
        ],
        zaiko: 5,
        cart: 0
    },
    methods: {
        addCart: function () {
            this.cart += 1
        },
        changeColor (cImage) {
            this.itemImage = cImage
        }
    }
})

index.html側では、v-bindディレクティブを使って、div要素のstyle属性の値とVueコードで用意した値を結びつけています。

main.js側では、ピンクのカラーコードの値cCode:”#ee6699″、および ブルーのカラーコードの値cCode:”#33aaee”を用意しています。

Vueコードで用意したカラーコードの値を取得して背景色に指定することで、ピンクとブルーのカラーボックスがスタイル表示されるようになりました。

次回へ続きます。