サルでもわかるWEBプログラミング

フリーソフトのみでホームページ作成

ユーザ用ツール

サイト用ツール


15.vue.jsのvuexでカウンター:index.html


文書の過去の版を表示しています。


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

vuexをなんとかして理解するために簡単なアプリを写経しています。前回の14.vue.jsのvuexで入力フォームでは、文字を入力すると、そのまま別のコンポーネントで表示するアプリを、vuexを用いて作成しました。

今回は、『カウンターアプリ』を作成しながら、vuexの理解を深めたいと思います。

初めてのVuex目次

すること

  1. vuexを用いてカウンターアプリを作成する
  2. 数字が表示されている(App.vueに表示させる)
  3. 『+1』を押すと、数字が1増える(components/counter.vueで『+1』ボタンを表示する)
  4. 『-1』を押すと、数字が1減る(components/counter.vueで『-1』ボタンを表示する)

今回は、https://qiita.com/ferretdayo/items/edcd2b6682148e477104を写経させていてだきました。

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

Demo

開発環境

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は、以下をコピペします。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>CodeSandbox Vue</title>
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"
rel="stylesheet"
/>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from "vue";
import App from "./App";
import Vuetify from "vuetify";
import "vuetify/dist/vuetify.css";
Vue.use(Vuetify);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: "#app",
components: { App },
template: "<App/>"
});
view raw src_main.js hosted with ❤ by GitHub

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

Vuetifyのテンプレートを適用

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

<template>
<div id="app">
<v-app id="inspire">
<v-toolbar color="indigo" dark fixed app>
<v-toolbar-title>Application</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>
Located two hours south of Sydney in the <br />Southern
Highlands of New South Wales, ...
</div>
</div>
</v-card-title>
<v-card-actions>
<v-btn flat color="orange">Share</v-btn>
<v-btn flat color="orange">Explore</v-btn>
</v-card-actions>
</v-card>
</v-flex>
</v-container>
</v-content>
</v-app>
</div>
</template>
<script>
export default {
data() {
return {}
}
};
</script>

これで、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のテンプレートの作成

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;

これでも、まだエラーが出ています。。。

右側の画面の更新画面を押すと、以下のように、vuexが動く準備ができたようです。

Counterコンポーネントを作成し,カウンター機能の追加

まずは、vuexを用いない方法で、カウンター機能を作成します。

  1. カウンターの表示、カウンターの『+1』、『-1』のボタンをcomponents/counter.vueに設置

でいってみたいと思います。

  • src/components/Counter.vueの新規作成
<template>
  <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">{{ count }}</h3>
        </div>
      </v-card-title>

      <v-card-actions>
        <v-btn v-on:click="decrement">-1</v-btn>
        <v-btn v-on:click="increment">+1</v-btn>
      </v-card-actions>
    </v-card>
  </v-flex>
</template>

<script>
export default {
  name: "Counter",
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    }
  }
};
</script>

  • HelloWorldコンポーネントでCounterコンポーネントを表示

src/App.vueの変更
(変更前)

(変更後)

App.vueとcomponents/Counter.vueを少しだけ変更して、以下のようになった。

+1をクリックと数字が1増えて、-1をクリックすると、数字が1減る。

次は、上記のカウンターの増減を、Vuexを用いる方法に書き換えていきます。

Vuexの説明

Vuexは図のようなデータの流れを持つ,状態管理のパターンです.

  1. ComponentはdispatchすることでActionsを実行する
  2. ActionsはCommitすることでMutationsを利用する
  3. MutationsはStateを変更する


Vuexの図:https://vuex.vuejs.org/ja/より引用

これだけでは何のことかさっぱりわかりません。。。
しかし、アプリが複雑になるほど、Vuexは必要になることは間違いないらしいので、やるしかありません!
(Vuexを用いないでデータをやり取りするためには、親コンポーネントと子コンポーネントの間でpropsと$emitのデータのバケツリレーが必要いなるためらしいです。)

今度こそ、上記のカウンターアプリをVuexを用いたアプリにします。

カウンター機能にVuexを利用

以下の3つを行う必要があるそうです。(参考:カウンター機能にVuexを利用

  1. src/store.jsファイルを新規作成し,state, actions, mutations, gettersを定義 (済み)
  2. src/main.jsにstoreファイルに書かれたstoreを登録 (済み)
  3. CounterコンポーネントからVuexを利用

src/store.jsファイルの編集

stateとかactionsとか言葉がたくさん出てきますが、以下を、100回くらい声に出して読んで、写経していくしかなさそうです。。。(参考:カウンター機能にVuexを利用

  1. stateには状態を持ちたい情報を定義する
  2. actionsでアクションを定義,commitすることでmutationsが実行される
  3. gettersはコンポーネントがデータを取得する際に利用される
  4. mutationsはstateの状態を変更する際に利用される
  1. gettersとmutationsのメソッドの引数には定義したstateが代入される
  2. actionsのメソッドの引数のcontextにはdispatch,commit,getters,stateを持つオブジェクトが代入される
    1. 引数に{ commit }とすると,commitだけ利用できる.

src/store.jsの変更
(変更前)

(変更後)

import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
/**
* 状態を保持したい変数の管理
*/
const state = {
count: 0
};
/**
* actionsはmutationsを利用して,アクションの処理を実装
*/
const actions = {
increment(context) {
context.commit("increment");
},
decrement({ commit }) {
commit("decrement");
}
};
/**
* gettersはstateの値を取得するのに利用
*/
const getters = {
getCount(state) {
return state.count;
}
};
/**
* mutationsは値の移り変わりの処理を実装
*/
const mutations = {
increment(state) {
state.count += 1;
},
decrement(state) {
state.count -= 1;
}
};
export default new Vuex.Store({
state,
actions,
getters,
mutations
});

actionsのメソッドの引数は、commitの場合は、上記の通り、2通りの書き方があるそうです。
(contextの中にcommitがあるだけですが。)

const actions = {
  increment(context) {
    context.commit("increment");
  },
  decrement({ commit }) {
    commit("decrement");
  }
};

src/main.jsにstoreを登録

上の方で、登録済みです。

import store from "./store";

// new Vue の中に、
  store,

CounterコンポーネントからVuexの利用

src/main.jsで追記したstoreを利用するにはthis.$storeから利用するとのことです。(参考:CounterコンポーネントからVuexの利用

上記サイトを写経しているだけで、詳しいことはよくわからないのですが、とにかく、$this.store.stateでstateをゲットしてくるらしいです。。。

  • state :stateにアクセスする際に利用
  • dispatch :actionsで定義したメソッド名を引数に渡すことで,actionを実行できる
  • getters :ここからgettersで定義したメソッドを利用できる
  • commit :mutationsに定義したメソッド名を引数に渡すことで,mutationを実行できる

今回のカウンターアプリでは、store.jsからのデータの取得にはcomputedで,storeのgettersで定義したcountの値を返すgetCountメソッドを利用します。

computed: {
    count () {
      return this.$store.getters.getCount
    }
  },

src/components/Counter.vue
(変更前)

(変更後)

このように、カウンターの初期値や、+1、-1の状態管理をvuexに移動しても、ちゃんと、カウンターが動くことが確認できる。

mapGetter, mapVuexのコードを少し発展させる

Vuexでカウンターアプリのリンク

https://qiita.com/ferretdayo/items/edcd2b6682148e477104
@ferretdayo
2017年12月23日に更新
IDOM Engineer Advent Calendar 201723日目
カウンターを作りながら,VueとVuexの基本をやる
→最初はこちらを写経でしょうか?

  1. Vuexを利用しないでカウンターアプリを作成
  2. Vuexを利用したカウンターアプリに変更
  3. Vuexのコードを発展させる(mapActions,mapState,mapGetters,mapMutationsの利用)

https://qiita.com/nasum/items/d17c0a628e6c32616b85
@nasum
2017年12月17日に更新
Vue.js #4 Advent Calendar 201717日目
改めて学び直すVuex
→カウンターアプリを作成します。

https://qiita.com/d-dai/items/7df318b9369be3d58a58
@d-dai
2018年11月25日に更新
Vuexの簡単なサンプルを作ってみた
→カウンターアプリを作成します。

ソースコード

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

DEMO

リンク


15.vue.jsのvuexでカウンター/index.html.1548492969.txt.gz · 最終更新: 2019/01/26 by adash333

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki