目次

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目次

14.vue.jsのvuexで入力フォーム

15.Vue.jsのvuexでカウンター

16.vue.jsのvuexでパスワード制限

17.Nuxt.jsのvuexでパスワード制限

18.Nuxt.jsとBulmaでハンバーガーメニュー

19.Nuxt.jsで画像一覧アプリ

すること

  1. vuexを用いて入力フォームを作成する

今回は、https://qiita.com/Takoyaki9/items/b6638fa1aec41464fdd1を写経させていてだきました。上記サイトにも、基礎から学ぶ Vue.js
という本が元ネタですと記載してありますが、この本はVue.js初めての方に(javascriptフレームワーク初めての方にも)非常にお勧めです。

ソースコード
https://codesandbox.io/s/0409x6y00l

Demo
https://0409x6y00l.codesandbox.io/

開発環境

Chrome
Codesandbox

Vue 2.5.2
Vuetify 1.4.2
Vuex 3.1.0

CodeSandboxで新規Vue.jsアプリを作成

最初に、CodeSandbox上で、新規Vue.jsアプリを作成し、CSSフレームワークVuetifyが利用できるように設定します。

  1. https://codesandbox.io/へ行き、画面右上の、『Create Sandbox』をクリック
  2. Vue をクリック
  3. Add Dependencyから、Vuetifyをインストール
  4. index.htmlの編集
  5. src/main.jsの編集

index.htmlと、src/main.jsは、以下をコピペします。

以上で、Vue.jsで、Vuetifyを利用する準備ができました。

Vuetifyのテンプレートを適用

src/App.vueに、以下のコードをコピペします。

これで、App.vueの土台が出来上がりました。

Vue.jsにVuexをインストール

Vuexを利用するための準備を行います。

  1. Add Dependencyから、Vuexをインストール
  2. Add Dependencyから、babel-polyfillをインストール
  3. src/main.jsの編集
  4. src/store.jsの新規作成

src/main.jsは、以下の2行を追加します。(追加する位置には注意する必要があります。)

import store from './store'

store,

(変更前)

(変更後)

この時点では、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の通りにやればできそうですが、、、

参考:https://vuetifyjs.com/ja/components/forms

stateやgetterにv-modelを使用する

基礎から学ぶ Vue.jsのp268を写経してみます。

→算出プロパティ(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

(変更前)

(変更後)

src/App.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の使い方を理解する

リンク

目次:目次

前:13.Vue.jsとWeb Speech ApiとFirebaseで認証つきボイスレコーダー(簡易議事録)

次:15.Vue.jsのvuexでカウンター