目次
14.vue.jsのvuexで入力フォーム
Vue.jsでは、『困難は分割せよ』という名言に従い、webページをコンポーネントという部品に分けて記載することにより、見通しのよいプログラミングを行っています。しかし、各コンポーネントで共通のデータをやり取りしたい場合は、データのバケツリレーのようになってしまい大混乱となります。そのため、データは、storeストアという一カ所に集めて、各コンポーネント←→ストアで、データのやり取りをする仕組みを提供するのがVuexというものです。
似たようなものに、ReactというjavascriptフレームワークのReduxがありますが、筆者には難しすぎて挫折しました。また、Angular(Ionic)というjavascriptフレームワークのproviderというものがありますが、こちらは、ソースコードを見るだけでなんとなく分かった気にはなれます。
当初、Nuxt.js で簡単な画像一覧アプリを作成するを写経して、画像一覧アプリを作成しようとしたのですが、vuexの部分がよく分からず、しかも実際に動くアプリを作成することができませんでした。Vue.jsアプリを作成していく上で、vuexは避けて通れない難関だと認識しました。そのため、非常に簡単なサンプルコードの写経から、順番にやってみたいと思います。
また、Vuexを理解するために、以下の3つの本を繰り返し読み、出来る限り写経しました。
初めてのVuex目次
すること
- vuexを用いて入力フォームを作成する
今回は、https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1を写経させていてだきました。上記サイトにも、基礎から学ぶ Vue.js
という本が元ネタですと記載してありますが、この本はVue.js初めての方に(javascriptフレームワーク初めての方にも)非常にお勧めです。
開発環境
Chrome Codesandbox Vue 2.5.2 Vuetify 1.4.2 Vuex 3.1.0
CodeSandboxで新規Vue.jsアプリを作成
最初に、CodeSandbox上で、新規Vue.jsアプリを作成し、CSSフレームワークVuetifyが利用できるように設定します。
- https://codesandbox.io/へ行き、画面右上の、『Create Sandbox』をクリック
- Vue をクリック
- Add Dependencyから、Vuetifyをインストール
- index.htmlの編集
- src/main.jsの編集
index.htmlと、src/main.jsは、以下をコピペします。
以上で、Vue.jsで、Vuetifyを利用する準備ができました。
Vuetifyのテンプレートを適用
Vue.jsにVuexをインストール
Vuexを利用するための準備を行います。
- Add Dependencyから、Vuexをインストール
- Add Dependencyから、babel-polyfillをインストール
- src/main.jsの編集
- src/store.jsの新規作成
src/main.jsは、以下の2行を追加します。(追加する位置には注意する必要があります。)
import store from './store' store,
この時点では、store.jsを作成していないので、エラーが出ます。
- src/store.jsのテンプレートの作成
src/store.jsを新規作成し、以下をコピペします。
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {} }); export default store;
これでも、まだエラーが出ています。。。
src/store.jsの編集
今回の、フォーム入力に関する状態管理のコードを記載します。https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1#storejsをコピペします。
気づいたら、なぜか、エラーが消えていました。
src/components/EditForm.vueの作成
文字入力を行うコンポーネントとして、src/components/EditForm.vueを新規作成して、https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1#editformvueのコードを写経します。
src/App.vueの編集
EditForm.vue で文字を入力 → store.js に入力した文字を保持 → App.vueで文字を表示
といった感じにしたいと思います。すると、以下のようなコードになるらしいです。
最初は宇宙語ですが、『computedでstoreのゲッターを呼んで値を取得する』らしいです。
とりあえず、src/App.vueを、https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1#appvueを少しだけ改変した以下のコードに変更します。
<template> <div id="app"> <v-app id="inspire"> <v-toolbar color="indigo" dark fixed app> <v-toolbar-title>Vue Vuex Form</v-toolbar-title> </v-toolbar> <v-content> <v-container fluid fill-height> <v-flex xs12 sm6 offset-sm3> <v-card> <v-img src="https://cdn.vuetifyjs.com/images/cards/desert.jpg" aspect-ratio="2.75" ></v-img> <v-card-title primary-title> <div> <h3 class="headline mb-0">Kangaroo Valley Safari</h3> <div>{{ message }}</div> </div> </v-card-title> <EditForm></EditForm> </v-card> </v-flex> </v-container> </v-content> </v-app> </div> </template> <script> import EditForm from "./components/EditForm"; export default { components: { EditForm }, data() { return {}; }, //vuexのstoreは基本的にcomputedと使う computed: { //main.jsでローカルにstoreを登録してるので、$storeが使える //ここではgettersに登録したmessageゲッターを使ってstoreのstateのmessageを取得している message() { return this.$store.getters.message; } } }; </script>
下のフォームに文字を記入すると、上に反映されています。うまくいっているようです。
src/components/EditForm.vueの編集
見栄えを改善するために、src/components/EditForm.vueを少しだけ変更したいと思います。
<input type=“text” のところを、vuetifyを使おうとして、 <v-text-field にすると、うまくいかない。。。
v-text-field のときは、data() にデータを入れていた。今回は、vuexのstoreにデータを送るので、computedを用いている。。。
基礎から学ぶ Vue.jsのp268の通りにやればできそうですが、、、
stateやgetterにv-modelを使用する
基礎から学ぶ Vue.jsのp268を写経してみます。
- stateはmutation以外からは書き換えていけない。
- getterもセッター機能がついていないため、入力はできない。
- v-modelを使用すると、自動的に値を書き換えようとするため、エラーになってしまう
→算出プロパティ(computed)のセッターを用いると、うまくいくらしいです。
// <template>の中の一部 <v-text-field v-model="message" label="以下に入力" required></v-text-field> // <script>の中の一部 message: { get() { return this.$store.getters.message; }, set(value) { this.$store.dispatch("doUpdate", value); } }
src/components/EditForm.vue
うまくいっているようです。
componentとstoreをバインドするヘルパー
getterやmutationを複数使用するとき、算出プロパティcomputedやmethodsにすべてを記述するのは冗長となってしまいます。
そのため、ヘルパーというものが用意されているそうです。
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
stateとgetterは算出プロパティcomputedに登録します。
mutationとactionはメソッドmethodsに登録します。
computed: { // ローカルの算出プロパティ myProperty() { ... }, ...mapGetters([ // this.messageをstore.getters.messageにマッピング 'message' ]), // メソッド名を変更したい場合はオブジェクトで定義 ...mapGetters({ // this.messageAliasをstore.getters.messageにマッピング messageAlias: 'message' }) }
カッコが、[]なのか、{}なのか、紛らわしいです。[]は配列、{}はオブジェクトなのだと思います。
組み合わせる必要がなければ、以下のように、オプションに直接、登録することもできるとのことです。
(しかし、これは汎用的ではないと思われます。)
computed: mapGetters(['message']), methods: mapActions(['add', 'update', 'remove'])
これは、次のメソッドでdispatchを使用できるようになるとのことです。
this.add('newItem!') // これは次のdispatchを使用したときと同じ this.$store.dispatch('add', 'newItem!')
という上記の解説を丸写ししてみましたが、実際、上記のコードを、どのようにmapGettersとmapActionsを使って変更したらよいのかは、残念ながらわかりませんでした。。。(爆)
vuex大まかなイメージと入力フォーム作成についてのリンク
https://qiita.com/aya02/items/933c6c55b8e4801f150a
@aya02
2018年11月28日に更新
爆速理解!超簡単Vuex入門①[初心者対象]
→なぜVuexを利用する必要があるのか?いつやるのか?に答えてくれます。
https://qiita.com/m_mitsuhide/items/f16d988ec491b7800ace
@m_mitsuhide
2018年07月31日に更新
Vue.js + Vuexでデータが循環する全体像を図解してみた
→最初はこれを読んでもさっぱりわからなかったのですが、他の記事を読んだり写経したりしてから、もう一度これを読んでみたら、かなりvuexが分かった気持ちになれました!
https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1
@Takoyaki9
2018年09月11日に更新
【初心者向け】状態管理にVuexを使ってみた【入門】
→入力フォームを作成します。一番最初に写経するのには、こちらがおすすめです。
https://qiita.com/_P0cChi_/items/ebf8fbf035b36218a37e
@_P0cChi_
2017年05月14日に更新
vue.js+Vuexチュートリアル
→お勧めです!入力フォームを作成します。
https://masayuki14.hatenablog.com/entry/2017/12/14/000000
2017-12-14
Vuexのはじめかた - Vuex入門者向けのはじめの一歩ガイド
→入力フォームを作成します。
https://qiita.com/tiwu_official/items/d66c5f3fe92794536d32
@tiwu_official
2017年09月14日に更新
Vue.jsとVuexでTodoListを作ってみた
→ToDoアプリ(create, updateのみ)をindex.htmlの1ファイルのみで作成します。https://qiita.com/tiwu_official/items/0b681d59c4c67dbad42cに、コンポーネント化したコードが解説されています。
mapStateとスプレッド演算子『...』に関するリンク
https://qiita.com/Statham/items/046649bff81c00ba275e
@Statham
2018年12月23日に更新
Vuex: mapStateの使い方を理解する
リンク