Vuexの使い方 [Laravel]
Vue.jsの「Vuex」(状態管理ライブラリ)を使用するとstate(状態)が管理できるので親、子、兄弟のコンポーネント間でデータを共有、参照可能です。
※今回使用するフレームワークはLaravelです。
作るもの
親コンポーネント 0
子コンポーネント 0
1. プロジェクトの生成
今回はLaravel 6系でやりますが、7、8などでもOKです。
composer create-project --prefer-dist laravel/laravel プロジェクト名 "6.*"
2. laravel/uiのインストール
Laravelのバージョンによっては数値が異なるのでご注意下さい。
cd プロジェクト名 // Laravel6 composer require laravel/ui:^1.0 --dev // Laravel7 composer require laravel/ui:^2.4
※2020/12/16時点ではLaravel8の情報はまだないようです。
3. Vue.jsのインストール
php artisan ui vue
4. 各パッケージのインストール
npm install
※node_modulesフォルダが生成されます。
5. Vuexのインストール
npm install vuex
6. ファイル構成と各ファイル
ファイル構成
次のファイルを編集及び新規作成します。
resources/js/app.js resources/js/store.js resources/js/components/app.vue resources/js/components/child.vue --- resources/views/welcome.blade.php
6-1. resources/js/app.js
require('./bootstrap'); // Vue.js window.Vue = require('vue'); // Vuex.Store import store from './store.js' Vue.component('app-component', require('./components/app.vue').default); const app = new Vue({ el: '#app', store: store, // ストアを追加する });
6-2. resources/js/store.js
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ // 共有するデータ state: { count: 0 }, // ミューテーション // ※stateのデータ変更はミューテーションが行う mutations: { setCount(state, payload) { state.count = state.count + payload; } }, // ゲッター getters: { getCount(state) { return state.count; } }, // アクション actions: { countAction(context, payload) { context.commit('setCount', payload); } } })
6-3. resources/js/components/app.vue
<template> <div style="margin:30px;"> <p>{{ msg }} <span>{{ count }}</span></p> <my-component msg="子コンポーネント"></my-component> <input type="button" value=" + " v-on:click="increment" /> <input type="button" value=" - " v-on:click="decrement" /> </div> </template> <script> import MyChild from './child.vue' export default { data: function () { return { msg: "親コンポーネント" } }, components: { // 子コンポーネント 'my-component': MyChild }, computed: { // ゲッターの呼び出し count(){ return this.$store.getters['getCount']; } }, methods: { // ディスパッチ(アクションを呼ぶ) increment() { this.$store.dispatch('countAction', 1); }, // ディスパッチ(アクションを呼ぶ) decrement() { this.$store.dispatch('countAction', -1); } } } </script> <style scoped> </style>
6-4. resources/js/components/child.vue
<template> <p>{{ msg }} <span>{{ count }}</span></p> </template> <script> export default { props: ['msg'], computed: { // ゲッターの呼び出し count(){ return this.$store.getters['getCount']; } } } </script> <style scoped> </style>
6-5. resources/views/welcome.blade.php
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="{{ url('css/app.css') }}" type="text/css"> </head> <body> <!-- ここでVue.jsの設定 --> <div id="app"> <app-component></app-component> </div> <script src="{{ url('js/app.js') }}"></script> </body> </html>
7. 開発用ビルド
CSS/JavaScriptを各1つのファイルにまとめる。
npm run dev
8. 実行する
php artisan serve
9. 解説
9-1. stateについて
stateのデータ変更はミューテーション(mutation)が行います。ミューテーションは同期処理で実行する必要があるので、一般的にアクション経由でミューテーションを呼び出します。
以下は、stateのデータを変更する流れです。
コンポーネント、ディスパッチ、アクション、ミューテーションとなります。
9-2. ヘルパー関数
ヘルパー関数にはmapState、mapGetters、mapMutations、mapActionsがあります。これらはVuexに慣れた方が「コードの簡素化」の為に使用します。詳細は公式サイトをご確認ください。
9-3. Vuexストアの分割
Vuexストア(store.js)は複数のモジュール(modules)に分割する事が可能です。その際は名前の衝突を防ぐために「namespaced: true」にします。詳細は公式サイトをご確認ください。
参考URL
API リファレンス (Vuex公式)