axiosでAPI通信をし取得したデータをどっかで保持して全部のページで使いたい!
どこのコンポーネントでも共通で使えるデータが欲しい !
必要な情報をどこからでも使えるようにstoreに保持できるとの事だったので調べてみました。
今回はVuexを利用したNuxt2での方法です。
storeでできること
storeを使うことで、アプリケーションの状態やデータを保持することができます。
ログインのステータスを保持したり、複数ページで利用する値を管理する際に使用します。
storeにはモジュールモードとクラシックモードがありますが、クラシックモードはNuxt3では廃止の予定です。
モジュールモード: store ディレクトリ内のすべての *.js ファイルが 名前空間付きモジュール に変換されます(index はルートモジュールとして存在します)
クラシックモード (廃止予定): store/index.js がストアインスタンスを返します
(参考)
https://develop365.gitlab.io/nuxtjs-2.8.X-doc/ja/guide/vuex-store/
そのため、この記事ではモジュールモードでの記述で説明していきます。
axiosのレスポンスを保持してみる
state・mutation・actionsを使用してAPIからデータ取得します。
.fa-hand-point-right{ color: #fcb900 }
state
要素の管理をするもの
dataプロパティと同じようなものと考える
mutations
状態の変更をするもの
actions
非同期処理を書くことができる
mutationを経由して(commit)stateを更新する
各コンポーネントからはactionで定義した処理が呼ばれる
.code.api::after{ content: ‘store/api.js’; background: #969998; color: #fff; }
import axios from 'axios'
export const state = () => ({
list: [],
});
export const mutations = {
setList(state, list) {
state.list = list;
},
};
export const actions = {
async getList ({commit}) {
const response = await this.$axios.$get('APIのURL')
commit('setList', response);
}
};
ちなみに、リロードするとstoreに保存されたデータは消えてしまいます。
永続化が必要であればvuex-persistedstateとかを使った方が良いです。
Vuexのヘルパーを使ってstoreで得たデータを呼び出します。
コンポーネントをバインドするヘルパー
コンポーネントのcomputedオプションを作成【状態を呼び出す】
mapState
mapGetters
コンポーネントのmethodsオプションを作成を作成【状態の変更】
mapActions
mapMutations
(参考)
https://vuex.vuejs.org/ja/api/#mapstate
mapActionsを使ってstoreのactionsのgetList()を呼んで
mountedでgetList()を動かして
mapStateで取得しています。
.code.vue::after{ content: ‘component/data.vue’; background: #969998; color: #fff; }
<template>
<p>{{ list }}</p>
</template>
<script>
import { mapActions, mapState } from 'vuex'
export default {
mounted () {
this.getList()
},
methods: {
...mapActions({
getList: 'api/getList',
}),
},
computed: {
...mapState({
list: (state) => state.api.list,
}),
},
}
</script>
共通で使えるデータをつくってみる
共通で使用できるデータとしてJSONデータを作成します。
.code.json::after{ content: ‘assets/json/ruby.json’; background: #969998; color: #fff; }
[
{ "text": "設定", "ruby": "せってい" },
{ "text": "送信", "ruby": "そうしん" },
{ "text": "返信", "ruby": "へんしん" },
{ "text": "検索", "ruby": "けんさく" },
]
storeフォルダに、json.jsを作成してruby.jsonを読み込ませます。
.code.data::after{ content: ‘store/json.js’; background: #969998; color: #fff; }
import jsonData from '@/assets/json/ruby.json'
export const state = () => ({
data: jsonData,
})
export const getters = {
// 全件表示
getAll: (state) => {
return state.data
},
// keyで検索
getDataByText: (state) => (text) => {
return state.data.find(data => data.text === text)
},
}
あとは使いたい箇所で呼び出しましょう!
全件をforで回してもよし。
.code.vue::after{ content: ‘component/data.vue’; background: #969998; color: #fff; }
<template>
<ul>
<template v-for="ruby in getAll">
<li :key="kana.index">{{ ruby.text }}</li>
</template>
</ul>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
getAll: 'json/getAll',
}),
},
}
</script>
子コンポーネントなんかでkeyで検索させて表示させれば、ふりがなを表示させたりなんて使い方もできます。
.code.vue::after{ content: ‘component/data.vue’; background: #969998; color: #fff; }
<template>
<ruby>
<rb>{{ data(translateText).text }}</rb>
<rp>(</rp><rt>{{ data(translateText).kana }}</rt><rp>)</rp>
</ruby>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
props:{
translateText: String,
},
computed: {
...mapGetters({
data: 'json/getDataByText',
}),
},
}
</script>
できた!