Vuexの前に試したいストアパターン
Vue.jsで複数のコンポーネントを作っていると、同じデータを別のコンポーネントで使いたくなることはありませんか?
まさに先日ちょっとした機能を実装している際に調べたので、ご紹介していきます。
Vuex
真っ先に思いついたのは、Vuex です。
Vue.jsの状態管理ライブラリとしてはデファクト的な立ち位置で、 とりあえずVuexを入れておけば大丈夫という印象があります。
ですが、今回実装していた機能はSPAではなく、既存ページに部分的にVue.jsを利用するようなモノでした。
複雑な親子コンポーネントもなく、Vuexでは機能が多すぎるので、もっとシンプルな方法は無いかなーと考えていました。
ストアパターン
Vue.jsのドキュメントを読んでいると、 ストアパターンという状態管理の実装方法が紹介されていました。
今回は、兄弟コンポーネントに共通して利用しているデータがあり、それぞれのコンポーネントで そのデータの変更をトリガーにして、APIからデータを取得したりするような要件でした。
複雑な状態操作は行っておらず、データを変更すると処理が1つ実行される程度です。
なので、データの状態だけを管理できればよく、データの操作を統一するような実装は不要でした。
公式ドキュメントでも紹介されていた 単純なストアパターン でのデータ共有で問題なく実装が完了し、リリースできました。
実装例
簡単な例で ストアパターンを使ってみます。 以下のような例題があったとして進めていきます。
AさんとBさんはとても仲良しで、いつも同じ色の服をおそろいで着ています。
3種類の色の中から、どれを選んでもAさんとBさんが同じ色の服を着ているようにしてください。
イメージとしては、こんな感じです。
ストアパターンを導入する前は、このようなコードでした。
<body> <main> <section id="a"> <h2>Aさん</h2> <ul> <li v-for="c in colors"> <label> <input type="radio" name="color-a" v-model="color" v-bind:value="c"> {{ c }} </label> </li> </ul> </section> <section id="b"> <h2>Bさん</h2> <ul> <li v-for="c in colors"> <label> <input type="radio" name="color-b" v-model="color" v-bind:value="c"> {{ c }} </label> </li> </ul> </section> </main> <script> new Vue({ el: '#a', data: { color: '', colors: [ 'オレンジ', 'ピンク', 'ホワイト', ], }, }); new Vue({ el: '#b', data: { color: '', colors: [ 'オレンジ', 'ピンク', 'ホワイト', ], }, }); </script> </body>
AさんコンポーネントとBさんコンポーネントがあり、それぞれに色の状態を持っています。
Vue.jsでは兄弟コンポーネント間でのデータ共有はサポートされていないため、Vuexやストアパターンを利用する必要があります。
ストアパターン実装後のコードです。 HTMLに変更は無いのでJavaScriptだけを載せています。
<script> // 状態を管理するためのオブジェクト const store = { color: '', colors: [ 'オレンジ', 'ピンク', 'ホワイト', ], }; new Vue({ el: '#a', // AさんとBさんで同じオブジェクトを利用する data: store, }); new Vue({ el: '#b', // AさんとBさんで同じオブジェクトを利用する data: store, }); </script>
store というオブジェクトを2つのコンポーネントで使うようにすることで、コンポーネント間で状態を共有できます。
まとめ
単純にデータを共有したいだけであれば今回紹介した ストアパターン で十分ではないでしょうか?
ストアパターンで実装した後に複雑になってきた場合に、やっと Vuex を導入するか検討する、という流れでもいいのではないかと思います。
とりあえずライブラリを導入するのではなく、必要最小限の機能を実装し、必要になってからライブラリの導入を検討する方が、実装スキルも身につくのではないでしょうか。