Rails+Vue.js+Webpackerによる「Create, Read, Update, Destroy」処理のチュートリアルを記述する。
なお,前提知識として,Railsチュートリアル終了程度を想定する。
<概要>
■ 本記事の内容
- Part4迄で作成した[BookHome.vue]のデータ処理について,Vuexの管理下に移行する。
- 今回のコードは,GitHubのコミット履歴で確認可能である。
- [Vuexの導入]から[ヘルパー関数による省略技法]まで
- 本記事の参考URL
■ 記事共通
-
目次
-
実装機能
- お気に入りの本に係る登録,参照,編集,削除処理
- 非同期通信(Ajax)による[Rails+Vue.js]のCRUD処理
- SinglePageApplication(SPA)
- ユーザー登録機能(JWTによるトークン認証)
-
開発環境
- MacOS Mojave
- Ruby(2.5.1)
- Ruby on Rails(5.2.1)
- Vue.js(2.6.10)
- Yarn(1.17.0)
- Webpack(4.39.2)
-
学習情報URL
<本文>
■ Vuexの導入
○1:Vuexをインストール
$ yarn add vuex
○2:[store.js]を作成
import Vue from 'vue'
import Vuex from 'vuex'
import router from '../router/router.js'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
mutations: {}
})
○3:[application.js]に[store.js]を登録
import Vue from 'vue'
import App from './App.vue'
import Router from '../router/router.js'
import Store from '../store/store.js'
const app = new Vue({
el: '#app',
router: Router,
store: Store,
render: h => h(App)
})
■ [fetchBooks]関連を移行
○1:[store.js]を修正
import Vue from 'vue'
import Vuex from 'vuex'
import router from '../router/router.js'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
// [state]がコンポーネントにおける[data]に相当
state: {
books: []
},
// [mutations]がコンポーネントにおける[methods]に相当
mutations: {
fetchBooks(state) {
state.books = [];
axios.get('/api/books').then((res) => {
for(var i = 0; i < res.data.books.length; i++) {
state.books.push(res.data.books[i]);
}
}, (error) => {
console.log(error);
});
}
},
})
○2:[HomeBook.vue]を修正
...
<script>
...
data: function() {
return {
bookInfo: {},
bookInfoBool: false,
// [store.js]に移行するため,[books]を削除
}
},
computed: {
// [store.js]から[books]を呼び出して,[BookHome.vue]のdata[books]に格納
books() {
return this.$store.state.books
}
},
mounted: function() {
// [fetchBooks]を[store.js]から呼び出すため,コード修正
this.$store.commit('fetchBooks')
},
methods: {
// [store.js]に移行するため,[fetchBooks]を削除
...
}
...
■ [setBookInfo]関連を移行
○1:[store.js]を修正
...
state: {
books: [],
bookInfo: {},
bookInfoBool: false
},
mutations: {
...
setBookInfo(state, { id } ) {
axios.get(`api/books/${id}.json`).then(res => {
state.bookInfo = res.data;
state.bookInfoBool = true;
});
}
}
})
○2:[HomeBook.vue]を修正
<script>
...
// [data:]は,全て削除
computed: {
books() {
return this.$store.state.books
},
// [bookInfo, bookInfoBool]を追加
bookInfo() {
return this.$store.state.bookInfo
},
bookInfoBool() {
return this.$store.state.bookInfoBool
}
},
...
methods: {
// [setBookInfo]を[store.js]から呼び出すため,コード修正
setBookInfo(id) {
this.$store.commit('setBookInfo', { id })
},
...
■ [deleteBook]関連を移行
○1:[store.js]を修正
...
mutations: {
...
deleteBook(state, { id } ) {
axios.delete(`/api/books/${id}`).then(res => {
state.bookInfo = '';
state.bookInfoBool = false;
});
}
...
○2:[HomeBook.vue]を修正
<script>
...
methods: {
setBookInfo(id) {
this.$store.commit('setBookInfo', { id })
},
// [deleteBook]のコードを修正
deleteBook(id) {
this.$store.commit('deleteBook', { id })
this.$store.commit('fetchBooks')
},
}
...
■ ヘルパー関数による省略技法
- ストアのstateを呼び出す際のコードが冗長であるため,ヘルパー関数を使用して,コードを簡略化する。
- mapStateと同様に,mapMutations, mapGetters, mapActions等も存在するが,本記事では使用しない。
- 参考URL
...
<script>
import axios from 'axios'
import { mapState } from 'vuex'
export default {
name: 'BookHome',
computed: mapState([
'books',
'bookInfo',
'bookInfoBool',
]),
...
/* 上記のコードと同等
~Ver.1:mapStateを使用して,異なるデータ名に格納したい場合~
computed: mapState({
books: 'books',
bookInfo: 'bookInfo',
bookInfoBool: 'bookInfoBool'
})
~Ver.2:デフォルト~
computed: {
books() {
return this.$store.state.books
},
bookInfo() {
return this.$store.state.bookInfo
},
bookInfoBool() {
return this.$store.state.bookInfoBool
}
}
*/
■ 特記事項
○1:[action,getter]について
今後チュートリアルで必要性が出てきたら追記します。
○2:Vuexの状態管理下に置くデータについて
Vuexの機能上,全てのデータを管理下に置くことは可能であり,複雑でもModuleを使用したら実装できるかと思います。
しかし,一つのコンポーネントでしか使用しないデータを共通の管理下に置くことは,冗長になり,管理が大変になることが予想されますので,以下の情報が判断の参考になるかと思い引用します。
- ステートに適したデータ
- サーバーからデータを取得中かどうかを表すフラグ
- ログイン中のユーザー情報など,アプリケーション全体で使用されるデータ
- ECサイトにおける商品の情報など,アプリケーションの複数の場所で使用される可能性のあるデータ
- コンポーネント側で持つべきデータ
- マウスポインタがある要素の上に存在するかどうかを表すフラグ
- ドラッグ中の要素の座標
- 入力中のフォームの値
【引用:Vue.js入門~基礎から実践アプリケーション開発まで~ 245-246.】
〜Part5: Vuex設定編終了〜
〜Part6: ユーザー登録&ログイン編へ進む〜