Tourismプロジェクトのブログ

活動の様子やメンバーの興味があることを書いていきます!

NuxtのVuexについて

はじめに

この記事は Vue や Nuxt を触ったことがある前提で書いてあります。 Vue や Nuxt が何かについて書いて欲しいという声があれば、いずれ(誰かが)記事を書くでしょう(たぶん)。

Vuexとは?

簡単にいうと Nuxt の状態管理ライブラリです。
と言われても???っていう人もいると思いますが、ざっくり説明するとログイン状態の情報や取得した API のデータなどを保存・管理できるようなイメージでいいと思います。
Nuxt では様々なコンポーネントを作成すると思いますが、それぞれに何度も同じ処理を書かずとも良くなるのでコードが見やすくなったり、データの管理がしやすくなり複雑化によるミスなども防げるかと思います。さらに、データへのアクセスの流れを一方向にすることができる(詳しくは後述)ため安定した管理がしやすくなります。
特に大規模な開発ではこういったことは必須になってくるので、ぜひ使ってみましょう。

データの流れ

まずは Vuex でのデータの流れをざっと理解しましょう。
以下はよく見るVuex公式ページの図です。

f:id:kit_tourism:20210904225448p:plain

Vuex ではデータは基本的に Action → Mutation → State → Vue Components という流れになります。 ちなみに Vue Components は State を直接参照せずに Getter を経由することが推奨されています。
初めての場合、これだけを読んでも何を言ってるのかさっぱりわからないと思いますが、まずは

  • Action → Mutation → State → Vue Components の流れ
  • State を参照するときはGetterを経由

ということを覚えておきましょう。
次にそれぞれについて詳しく見ていきましょう。

Action

Action は Mutation を介することでStateを更新する役割を持ちます。 大切なのはAction が直接 State を変更することはなく、必ず Mutation を介するということです。これによりデータの流れが一方向に守られます。
バックエンドから API を叩くような処理はここで書きます。
また、非同期での処理を記述することも可能です。
以下は id と name を持つnewDataを取得した仮のデータとして、それをStateにMutationを介して更新するようにしています。

const actions = {
  fetchData({ commit }) {
    // これが取得したデータだとする
    const newData = {
      id: 1,
      name: 'data1'
    }

    // commitの引数は(Mutationの関数名, 更新データ)となる
    commit('addData', newData)
  }
}

Mutation

State を更新することができる唯一の手段が Mutation です。
また、Mutation の関数を直接呼ぶことはできず、Action で書いたようにcommit()を使用して呼び出します。
状態変化を予測可能なものにするため、Mutation は必ず同期的でなければなりません。
以下は配列である State のdataに新しく更新したデータを追加する処理です。

const mutations = {
  addData(state, newData)
    state.data.push(newData) 
}

State

Stateはデータの入れ物で、ユーザーのログイン情報など複数のコンポーネントでを跨ぎたい情報を管理します。
以下ではdataという State を定義しています。

const state = () => ({
  data: []
})

Getter

GetterはStateの値から算出される値を返します。 先ほども書いた通りコンポーネントから State を参照する場合は必ずこの Getter を経由します。 以下では State のDataを参照しています。

const getters = {
  getData(state) {
    return state.data
  }
}

コードまとめ

先程まではデータの流れの順に紹介しましたが、実際にコードにすると読みにくいので以下のような順で書くことが多いです。

export const state = () => ({
  data: []
})

export const mutations = {
  addData(state, newData)
    state.data.push(newData) 
}

export const actions = {
  fetchData({ commit }) {
    // これが取得したデータだとする
    const newData = {
      id: 1,
      name: 'data1'
    }

    // commitの引数は(Mutationの関数名, 更新データ)となる
    commit('addData', newData)
  }
}

export const getters = {
  getData(state) {
    return state.data
  }
}

component などでの操作

State を取得したいときは以下のように書きます。

this.$store.getters["storeのファイル名/getData"]

State を更新したいときは以下のように書きます。

this.$store.dispatch("storeのファイル名/fetchData")

さいごに

Vuexなかなかとっつきにくいですよね。
個人で小さいアプリを作ったりするだけであれば正直使わなくてもいいと思いますが、それなりの規模のアプリを作るときにはこういった状態管理は必須になってくるので、がんばって勉強しましょう。概念的な部分を理解してしまえば、例えば React での Redux とかの他の状態管理ライブラリも理解しやすくなると思います。
僕自身もまだ完璧に理解しきれているかと言えば自信はないので、これからも勉強を続けていこうと思います。
この記事が少しでも理解の役にたったら幸いです。

執筆者: せきやん(@sekiyan372)

参考

zenn.dev

blog.mintsu-dev.com