Vue.jsを利用したサイコロアプリ
コンポーネントとは
コンポーネント(Component) とはVue.jsでページを構成する部品のことです. ページの部分的な機能をコンポーネントとして実装することで,ページ内に複数配置したり再利用が可能になります. 今回は サイコロの目 をコンポーネントとして実装し,1から6の目を配置します.
サイコロアプリ
それでは サイコロアプリ を実装して行きましょう. 下記が完成したソースコードです. 「サイコロを振る」というボタンをクリックすると,1から6のいずれかの目が緑色になります.
See the Pen NWxpRYa by Naoto Mukai (@nmukai) on CodePen.
コンポーネントの作成
サイコロの目は divタグで実装します.
まずは,divタグをデザインするための CSS を下記のように記述します.
pipStyleとpipFocusの2つのクラスがあり,これをdivタグに適用します.
.pipStyle{
width: 50px;
height: 50px;
border: 1px solid black;
text-align: center;
display: table-cell;
vertical-align: middle;
}
.pipFocus{
background: #00ff00;
}
div{
margin: 5px;
}
pip という名前でコンポーネントを実装します.
この名前はHTMLでタグ名として用いられます.
オプションには props と template を設定しています.
props はpipタグの属性として渡されるデータを指しています.
この場合,渡されたデータはflagという変数に格納されます.
templateはコンポーネントをHTMLタグとして記述したときの実体であり,
ここではサイコロのマス目を表すdiv要素です.
ここで,v-bind:class='{pipFocus: flag}'に注目します.
これは,v-bindディレクティブを利用したCSSのクラスの設定を表しており,
flagがtrueのときにだけ,pipFocusを有効にすることを意味しています.
このようにv-bindディレクティブを用いてCSSの切り替えが可能です.
また,<slot></slot>にも注目しましょう.
このslotタグは特別な役割を持ち,pipタグで囲まれた文字列を表します.
Vue.component("pip", {
props: ["flag"],
template: "<div class='pipStyle' v-bind:class='{pipFocus: flag}'> <slot></slot> </div>"
})
new Vue({
el: "#main"
});
コンポーネントを利用してHTMLを記述します.
pipタグには,flag属性を設定しています.
このflag属性がtrueのときだけ,pipFocusが有効になるため,
サイコロの1の目だけが緑色になっていることが確認できます.
また,slotタグはpipタグで囲まれた文字列(1または2)に置き換わっています.
<div id="main">
<div>
<pip flag="true">1</pip>
<pip flag="false">2</pip>
</div>
<div>
<button>サイコロを振る</button>
</div>
</div>
Vueクラスの拡張
次にVueクラスを拡張し,サイコロの状態をデータバインディングで表現することにしましょう.
dataオプションで,サイコロの目を表すpips配列と,クラスの有効を切り替えるflags配列を定義しています.
new Vue({
el: "#main",
data: {
pips: ["1", "2", "3", "4", "5", "6"],
flags: [true, false, false, false, false, false]
}
});
上記のpips配列とflags属性を利用してHTMLを書き換えます.
このとき,v-forディレクティブを利用して,pips要素の数だけpipタグを生成しています.
ここで,(pip, i) in pipsはインデックス付きの繰り返しであり,pipには配列の要素,iには配列のインデックスが代入されます.
<div id="main">
<div>
<template v-for="(pip, i) in pips">
<pip v-bind:flag="flags[i]"> {{ pip }} </pip>
</template>
</div>
<div>
<button>サイコロを振る</button>
</div>
</div>
rollメソッドの実装
サイコロの目をランダムに決定するrollメソッドを定義します.
配列のインデックスとなる0から5の乱数を生成し,
この値に応じてflags配列のtrueの位置を変更します.
このとき,Vue.set()メソッドを利用して,
配列に変更があったことを知らせる必要があります(this.flags[i] = true;では動的に変更されない).
new Vue({
el: "#main",
data: {
pips: ["1", "2", "3", "4", "5", "6"],
flags: [true, false, false, false, false, false]
},
methods: {
roll: function(){
dice = Math.floor(Math.random() * 6);
for(i=0; i<this.flags.length; i++){
if(i == dice){
Vue.set(this.flags, i, true);
}
else{
Vue.set(this.flags, i, false);
}
}
}
}
});
最後にv-onディレクティブでrollメソッドを呼び出しましょう.
「サイコロを振る」をクリックすると,緑色の目がランダムに変更されれば完成です.
<div id="main">
<div>
<template v-for="(pip, i) in pips">
<pip v-bind:flag="flags[i]"> {{ pip }} </pip>
</template>
</div>
<div>
<button v-on:click="roll">サイコロを振る</button>
</div>
</div>



