LoginSignup
6
8

More than 1 year has passed since last update.

【Vuex】Vuex をざっくり理解

Last updated at Posted at 2022-09-08

Vuexについて勉強してみて、ざっくりと理解できた内容についてまとめてみました。
間違いなどあればご指摘いただけると幸いです。

この記事でわかること

Vuex ってざっくりどんな仕組みになっているのか。
・使うことで何が嬉しいのか。

Vuex とは

ものすごくざっくり言うと、Vuexはアプリのデータを管理するための簡易的なDBみたいなものです。
極端に言うと単なる入れ物みたいなイメージだと私は考えています。

なので、やってることは
入れ物を用意して、そこに値を出し入れしているだけ

Vuexのメリット

データを1箇所で集中管理でき、ソースコードの可読性が向上、+デバックが容易になる。

Vuexのメリットを語るには、Vuexがない世界を想像すると理解しやすいです。

vueでは、コンポーネント間でpropsで親から子へデータを受け渡し、
$emitで子から親にデータ送ることができます。

開発が進むことで、大体コンポーネントの種類も増えていきます。

コンポーネントが増えることで、当然ながらデータの受け渡しも増大します。

その結果、データがどこで変更されたか等のデータの流れが追いづらくなり、
メンテナンスが困難なコードとなってしまい困ります。( ;∀;)

このような問題を解決するために生まれたのがVuexです。

Vuex 全体の流れ

Vuexの中心にいるのが、storeと言われるアプリケーションのデータ状態を保持するコンテナで、
このstoreには4つの機能があります。(state, mutations, actions, getters
それぞれの役割についてみていきましょう。

※使用しているソースコードは公式から引用しています。

state

stateは、アプリケーション全体のデータの状態を管理します。
ここで管理したいデータを「名前: 初期値」みたいな形で定義します。

const store = createStore({
  // 「名前: 初期値」 の形で定義する
  state: {
    count: 1
  }
})

※ アプリケーションごとに1つしかストアは持たないことに注意が必要です。

mutations

mutationsは、stateの更新だけを行います。

muitationsには非同期処理を含んではいけないことに注意が必要です。
その理由は、非同期処理とstateの管理が混在すると、状態管理が追跡しにくくなるからです。

Vuex のストアの状態を変更できる唯一の方法は、mutationsをコミット(実行)することです。

使い方は以下のように、Vuexの状態(state)を第1引数として受け取り、状態の変更を行います。

const store = createStore({
  state: {
    count: 1
  },
  mutations: {
    // ステート管理に必要なメソッドを用意する
    increment (state) {
      // 状態を変更する
      state.count++
    }
  }
})

また、引数の指定も可能で、この追加の引数は、特定のミューテーションに対するペイロードと呼ばれます。

// ...
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}

actions

actionsは、mutationsの呼び出しを行います。
また、actions自体は直接stateを変更できないことに注意が必要です。
また、非同期なAPI通信もここで行います。

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      // mutationsを呼び出している
      context.commit('increment')
    }
  }
})

ここで登場したcontextはコンテキストオブジェクトと呼ばれ、ストア配下にアクセスするために
以下のプロパティを提供します。
[Vuex] mutations, actions, gettersの引数について を参考にしました。

image.png

今回で言うと、contextオブジェクトにあるcommitを呼びだし、mutationsを実行しています。

また、渡されたcontextオブジェクトからプロパティであるcommitを取り出し、
同名の変数に渡すことで以下のように短縮して記述することもできます。

///
  actions: {
    increment ( { commit } ) {
      commit('increment')
    }
  }
})

getters

gettersは、stateの値を算出したものを返す場合に役立ちます。

computedと使い方はかなり近いです。

stateの内容を演算/加工処理をコンポーネント側で書くことできますが、
データの集中管理という観点でstoreの中に書いた方が利便性が向上します。

以下が具体的なコードです。

const store = createStore({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos (state) {
      return state.todos.filter(todo => todo.done == true)
    }
  }
})

gettersは第1引数として、stateを受け取ります。
filterjavascript標準のメソッドで条件式(todo.done == true)を満たす要素を取得します。

まとめ

上記をまとめると以下のような図式になります。
image.png

上の図のように、データの流れが一方通行になっています。
非同期通信をactionsで行い、その後にmutationsを実行することでstateを変更している。
stateが変更されたことを検知し、gettersstateのデータを再取得して、画面に反映させる仕組みです。

最後に

説明していてなんですが、Vuexで管理されるデータはどこからでも参照、変更できる
グローバル変数であるため、使いどころも難しいと感じます。

影響範囲が大きい分、意識しないといけないものが増えるので、読むときや修正する際に
精神的な負担が高いコードになってしまう危険性もあるみたいです。

ここら辺はトレードオフで考えなければいけないんだなぁと。

参考文献

これからはじめるVue.js 3実践入門

6
8
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
6
8