15
13

More than 5 years have passed since last update.

【Vuex】Vue CLIでVuexを簡単に始める

Posted at

以前にこちらの記事を投稿したんですが、今回はVue CLIで同じことを試してみます。
【Vuex】CDNでVuexの最初の一歩を踏み出す

Vue CLIのプロジェクト作成

前提として、Vue CLIの起動に必要なパッケージは全てグローバルインストールされている状態です。
【Vue.js】Vue CLIでVue.jsを動かす〜プロジェクト作成まで

$ vue init webpack my_vuex_test

Vuexのインストール

$ npm install vuex

インストール後にパッケージの脆弱性や依存情報についてメッセージが出力されますが、学習用のため、今回はこのまま進めました。

ディレクトリ構造

srcディレクトリ直下の既存ファイルを若干編集しています。
使用しているファイルに限定すると、以下の構造になります。

src
  ├── components
  │   ├── App.vue      // 編集
  │   └── Counter.vue  // 新規ファイル
  ├── main.js          // 編集
  └── store            // 新規ディレクトリ
      └── index.js     // 新規ファイル

// 最終的に、ルートディレクトリ直下の``index.html``により出力される

用語の確認

簡単に確認します。
内容は公式サイトからの引用です。

説明だけだと分かりにくいので、実際に使いながら覚えていきます・・・

ストア

信頼できる唯一の情報源。
アプリ1つにつき、1つだけ作ることができる。

Vuex アプリケーションの中心にあるものはストアです。"ストア" は、基本的にアプリケーションの 状態(state) を保持するコンテナです。

ステート

ストアの状態そのもの。
ストアの状態はここから呼び出される。

Vuex は 単一ステートツリー (single state tree) を使います。つまり、この単一なオブジェクトはアプリケーションレベルの状態が全て含まれており、"信頼できる唯一の情報源 (single source of truth)" として機能します。これは、通常、アプリケーションごとに1つしかストアは持たないことを意味します。単一ステートツリーは状態の特定の部分を見つけること、デバッグのために現在のアプリケーションの状態のスナップショットを撮ることを容易にします。

ミューテーション

ストアの状態を変更する手段。

実際に Vuex のストアの状態を変更できる唯一の方法は、ミューテーションをコミットすることです。Vuex のミューテーションはイベントにとても近い概念です: 各ミューテーションはタイプとハンドラを持ちます。ハンドラ関数は Vuex の状態(state)を第1引数として取得し、実際に状態の変更を行います。

ソースコード

処理の流れ

このようになるかと思います。

  1. store/index.jsでストアをセットする
  2. main.jsでストアをimportする
  3. main.jsにstoreオプションを設定し、コンポーネントにストアを注入する
  4. 同じくmain.jsでimportしているApp.vueに、注入されたストアが反映される
  5. App.vueからimportしているCounter.vueにも、注入されたストアが反映される

公式サイトより引用します。

ルートインスタンスに store オプションを渡すことで、渡されたストアをルートの全ての子コンポーネントに注入します。これは this.$store で各コンポーネントから参照することができます。

ルートのmain.jsでstoreオプションを使用することにより、枝葉であるコンポーネントへストアが注入されます。
注入されたストアは、this.$store.state.countという書き方でApp.vueとCounter.vueの双方から呼び出しています。

store/index.jsとmain.jsでstore.commit('increment')を行なっているため、最終的にcountの結果は2になります。

npm run devでサーバーを立ち上げると、ブラウザ上で確認できます。

index.html

特に編集はしていません。

index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>my_vuex_test</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

main.js

main.js
import Vue from 'vue';
import Vuex from 'vuex';

// index.jsの場合はファイル名を指定する必要はない
import store from './store'

import App from './components/App'

Vue.use(Vuex);

new Vue({
  el: '#app',
  store,
  components: { App },
  template: '<App/>' // '<app></app>'でも可
})

store.commit('increment')

store/index.js

store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})

store.commit('increment')

export default store

App.vue

App.vue
<template>
  <div id="app">
    <p>App: {{ count }}</p>
    <Counter/>
  </div>
</template>

<script>
import Counter from './Counter'

const App = {
  components: {
    Counter
  },
  computed: {
    count() {
      return this.$store.state.count
    }
  }
}

export default App
</script>

Counter.vue

Counter.vue
<template>
  <div id="counter">
    <p>Counter: {{ count }}</p>
  </div>
</template>

<script>
  const Counter = {
    computed: {
      count() {
        return this.$store.state.count
      }
    }
  }

  export default Counter
</script>

Vuexには他にもgettersなどの機能がありますが、少しずつ進めていきます。

15
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
13