Vuexをインストール
本章ではVuexを使って変数の定義と表示を行います。
Vuex
https://vuex.vuejs.org/ja/
インストールはこれでできます。
$ npm install vuex --save
プロジェクトのルートディレクトリで行ってください。
(package.json
があるディレクトリです)
Vuexに変数定義
Vuexを導入する目的はコンポーネントに依存しない共通の変数や関数をもちたいのが主です。
Vuexを使うためにsrc配下にstore.jsを作成します。
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {},
mutations: {}
})
export default store
これはお決まりの書き方で、このような意味になります。
- VueとVuexを読み込む
- VueでVuexを使用する
- storeを定義
- storeを外部で使うためにexportする
このstoreという変数が共通で使えるもので、各コンポーネントから呼び出して使っていきます。
storeに何を定義するかというと変数と関数です。
正確には4種類あります
変数を定義する
・ゲッター(getters)
変数をフィルタリングする
・ミューテーション(mutations)
変数を更新する
・アクション(actions)
外部通信を含めた複合的な処理を行う
ここではステートとミューテーションのみ扱います。
ステートには以下の変数を用意します。
- 駒の一覧 (komaList)
- Playerの点数 (playerPoint)
- Comの点数 (comPoint)
- Playerが獲得した駒 (playerKomadai)
- Comが獲得した駒 (comKomadai)
- Playerが選択できる駒 (playerSelectable)
- Comが選択できる駒 (comSelectable)
これらをstateに定義します。
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
// 追加
const komaIndexList = ["fu", "kyosha", "keima", "gin", "kin", "kaku", "hisha"]
const store = new Vuex.Store({
state: { // 以下追加
komaList: {
fu: { point: 1, label: "歩" },
kyosha: { point: 3, label: "香" },
keima: { point: 4, label: "桂" },
gin: { point: 6, label: "銀" },
kin: { point: 7, label: "金" },
kaku: { point: 9, label: "角" },
hisha: { point: 10, label: "飛" }
},
playerPoint: 0,
comPoint: 0,
playerKomadai: [],
comKomadai: [],
playerSelectable: Object.assign([], komaIndexList),
comSelectable: Object.assign([], komaIndexList)
},
mutations: {}
})
export default store
それぞれの変数の説明です。
- 駒の一覧 (komaList)
型:オブジェクト
keyに駒の英語表記でポイントと表示ラベルを持ちます
komaListは更新されません - PlayerとComの獲得ポイント (playerPoint, comPoint)
型:Number
初期値:0
駒を獲得したらその駒の点数が加算されます - PlayerとComの獲得した駒 (playerKomadai, comKomadai)
型:配列
初期値:空
駒を獲得したら["fu", "kyo"]
のよう増えていきます - PlayerとComの選択できる駒 (playerSelectable, comSelectable)
型:配列
初期値:["fu", "kyosha", "keima", "gin", "kin", "kaku", "hisha"]
使用した駒は減っていき最後には空になります
これでステートの変数定義は終わりです。
※Object.assignについて
Object.assign([], komaIndexList)
はkomaIndexList
をコピーするためです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
仮にこのようにするとplayerSelectableとcomSelectableは内部的には同じものになってしまい正しく動作しません。
playerSelectable: komaIndexList,
comSelectable: komaIndexList
Vuexのステートをコンポーネントで使用
store.js
のステートで定義した変数をコンポーネントで使っていきます。
そのための準備としてmain.js
でstore.js
を読み込みます。
import Vue from "vue"
import App from "./App.vue"
import store from "./store.js" // 追加
Vue.config.productionTip = false
new Vue({
store, // 追加
render: (h) => h(App)
}).$mount("#app")
これでコンポーネントから$store.state
という名前でstore.js
のstate
を使うことができます。
テンプレートで使う時は$store.state
で、JSで使う時はthis.$store.state
になります。
それではkomaList
を使って将棋盤の駒表示を書き換えます。
まずはCom側から。
<div class="shogi-ban">
<table>
<tbody>
<tr class="com-row">
<td v-for="(koma, index) in $store.state.komaList" :key="index">
{{ koma.label }}
</td>
</tr>
$store.state.komaList
をv-for
でループすれば駒の数だけ<td>
が作られます。
koma
には{ point: 1, label: "歩" }
が、index
にはfu
が入っていきます。
タグの中身で{{}}
を使えば表示することができます。
同じ要領でPlayer側も書き換えます。
<tr class="player-row">
<td v-for="(koma, index) in $store.state.komaList" :key="index">
{{ koma.label }}
</td>
</tr>
</tbody>
</table>
</div>
mapStateで書き換える
$store.state
は大変便利です。
ただ少し記述が長いので短縮する方法があります。
$store.state
を短縮して使えるmapState
というヘルパーがあるのでそちらで書き換えていきます。
importでmapState
を読み込みます。
<script>
import { mapState } from "vuex" // 追加
import GameRule from "./GameRule"
import ComKomadai from "./ComKomadai"
...
</script>
computed
に...mapState(["komaList"]),
と書けば、$store.state.komaList
をそのままkomaList
として使うことができます。
computed: {
...mapState(["komaList"]), // 追加
kyokumen() {
return this.phase === 1 ? "初手" : this.phase + "手目"
},
displayResult() {
return this.gameResult ? this.gameResult : this.phaseResult
}
}
mapState
の書き方は色々あって少しややこしいのですが、以下のことを覚えておけば良いと思います。
- mapStateはVuexのstateを短縮して使えるヘルパーである
$store.state
が不要になるimport { mapState } from "vuex"
で読み込む- computedに使うstateを記載する
- 記載の仕方は色々ある
ちなみに上記のcomputed
は以下と同じ意味になります。
computed: {
komaList() {
return this.$store.state.komaList
},
kyokumen() {
return this.phase === 1 ? "初手" : this.phase + "手目"
},
displayResult() {
return this.gameResult ? this.gameResult : this.phaseResult
}
}
後々...mapState(["komaList", "playerPoint", "comPoint"])
のように増やしていけるので、ここでは...mapState
を使います。
...
はスプレッド構文と呼ばれるものでES2015のJSではよく出てきます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
では駒一覧の表示を変えていきます。
変えるところは$store.state
を消すだけです。
Com側
<div class="shogi-ban">
<table>
<tbody>
<tr class="com-row">
<td v-for="(koma, index) in komaList" :key="index">
{{ koma.label }}
</td>
</tr>
Player側
<tr class="player-row">
<td v-for="(koma, index) in komaList" :key="index">
{{ koma.label }}
</td>
</tr>
</tbody>
</table>
</div>
駒台にmapStateを使う
Comの駒台でもmapStateを使ってポイントを表示していきます。
<script>
import { mapState } from "vuex"
export default {
computed: {
...mapState(["komaList", "comKomadai", "comPoint"])
}
}
</script>
comPoint
をテンプレートで使います。
<div class="com-point">{{ comPoint }}</div>
computed
のkomaList
とcomKomadai
は後で使用します。
上記のcomputed
はこれと同義です。
computed: {
komaList() {
return this.$store.state.komaList
},
comKomadai() {
return this.$store.state.comKomadai
},
comPoint() {
return this.$store.state.comPoint
}
}
Playerのポイントも同様にmapStateで表示します。
<script>
import { mapState } from "vuex"
export default {
computed: {
...mapState(["komaList", "playerKomadai", "playerPoint"])
}
}
</script>
<div class="player-point">{{ playerPoint }}</div>
ポイントの初期値:0が表示されていればOKです。
ここまでのコードはこちらにあります。
本章までで変数の定義ができたので、 次章 からはこれらを更新する関数を作っていきます。