Vue入門10 computedプロパティで計算結果を表示

Vue入門の第10回(第1回はこちら)です。今回は、computedプロパティを使って計算結果として表示する方法を学びます。

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>{{ itemFullName }}</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, itemColor.cName)" 
		    v-bind:style="{ backgroundColor: itemColor.cCode }" 
		    style="width:30px; height:30px; margin-bottom:20px;"
		    >
		    </div>

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

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

このindex.htmlの書き換えでは、2か所の変更が行われています。変更の1点目は、<h2>{{ itemFullName }}</h2>の行です。この変更では、変数名が itemNameから itemFullName に変更されています。

変更の2点目は、v-on:click=”changeColor(itemColor.cImage, itemColor.cName)” の行です。この変更では、引数に新しく itemColor.cName が追加されています。

main.jsを書き換える

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

var app = new Vue({
    el: '#app',
    data: {
        itemName: 'キッズ靴下',
        itemColorName: 'ピンク',
        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,
        soldout: false
    },
    methods: {
        addCart: function () {
            this.cart += 1
            this.zaiko -= 1
            if (this.zaiko <= 0) {this.soldout = true}
        },
        changeColor (cImage, cName) {
            this.itemImage = cImage,
            this.itemColorName = cName
        }
    },
    computed: {
        itemFullName() {
            return this.itemName + '(' + this.itemColorName + ')'
        }
    }
})

このmain.jsの書き換えでは、3か所の変更が行われています。 最も重要な変更は、computed: { ~ }の部分が追加されたことです。ここでは、変数itemFullNameの計算値が定義されています。

2点目の変更は、 itemColorName: ‘ピンク’, が追加されていることです。 変数itemColorName は、 itemFullNameの計算に利用するデータであり、計算結果が商品カラー名として画面表示されます。

3点目の変更は、changeColorメソッドのなかにthis.itemColorName = cNameが追加されていることです。ここでは、変数itemColorName に現在選択されている商品カラー名を代入しています。

表示を確認してみる

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

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

カラーボックスをクリックすると、(ピンク)⇔(ブルー)の色名表示が切り替わるようになれば成功です。

今回の変更のポイント

今回の変更のポイントは、 computedプロパティを使って 計算結果として商品名を表示するようにしたことです。

以下のコードでは、itemFullNameの値をthis.itemNameとthis.itemColorNameを組み合わせた計算結果として作成しています。

computed: {
    itemFullName() {
        return this.itemName + '(' + this.itemColorName + ')'
    }
}

上記コードのように、computedプロパティを使えば変数の値を動的に計算結果として作成できるというのが今回のポイントです。

それ以外は、この部分に合わせて必要に応じて変更しただけですが、簡単に確認しておきましょう。

まず、index.html側では、計算結果を表示する部分の変数名を変更しています。

<h2>{{ itemFullName }}</h2>

また、カラーボックスをクリックした際に色名の表示が切り替わって欲しいので、以下の部分では引数をひとつ追加しています。追加した引数は「itemColor.cName」の部分です。

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

上記で追加した引数は、main.js側のchangeColorメソッドに渡されて表示切替に利用されます。以下のコードの「this.itemColorName = cName」の部分で利用されています。

changeColor (cImage, cName) {
    this.itemImage = cImage,
    this.itemColorName = cName
}

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>{{ itemFullName }}</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, itemColor.cName)" 
		    v-bind:style="{ backgroundColor: itemColor.cCode }" 
		    style="width:30px; height:30px; margin-bottom:20px;"
		    >
		    </div>

		    <button 
		    v-on:click="addCart" 
		    v-bind:disabled="soldout"
		    >買い物かごの中身を増やす</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: 'キッズ靴下',
        itemColorName: 'ピンク',
        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,
        soldout: false
    },
    methods: {
        addCart: function () {
            this.cart += 1
            this.zaiko -= 1
            if (this.zaiko <= 0) {this.soldout = true}
        },
        changeColor (cImage, cName) {
            this.itemImage = cImage,
            this.itemColorName = cName
        }
    },
    computed: {
        itemFullName() {
            return this.itemName + '(' + this.itemColorName + ')'
        }
    }
})

繰り返しになりますが、今回の変更のポイントは、 computedプロパティを使って 計算結果として商品名を表示するようにしたことです。

computedプロパティは、動的な表示切替などを行う際に便利な機能です。いま作成しているくらいのシンプルなプログラムでは便利さを実感しづらいかもしれませんが、画面を動的に何パターンかに表示し分ける場合などには大変便利です。computedプロパティ というものがあるということを覚えておきましょう。

次回へ続きます。