- 開発技術
Vuexで中~大規模なSPAを構築する【Vue.js】
- #VueJS
そもそもVue.jsとは?
【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc. 詳細はこちらから>
「Vue.jsまたはVueは、Webアプリケーションにおけるユーザーインターフェイスを構築するための、オープンソースのJavaScriptフレームワークである(Wikipedia)。」
VueはJavaScriptのフレームワークで、HTML、CSS、JavaScriptの書き方を知っていれば簡単に高機能なアプリケーションを作ることができます。
何故Vuexを使うのか?
VueでSPA(シングルページアプリケーション)を構築する際、プロジェクトの規模が肥大化していくとコンポーネント間のデータの受け渡しが複雑になり管理が難しくなります。
例えばコンポーネントが多数存在し、コンポーネント間で受け渡すパラメータをpropsやemitで何度も受け渡しするとパラメータの流れを追うことが難しくなります。
Vuexを使うことでデータの管理を一元化することができ、規模の大きなプロジェクトでのデータ管理が容易となります。
VuexでWEBアプリを構築してみよう
- VueとVuexのインストール
Vue CLIを利用して初期環境の構築を行います。Vue CLIをインストールするためにnpmを使用します(npmを使用するにはNode.jsをインストールする必要がありますが今回は割愛します)。Vue CLIのインストール
1npm install -g @vue/cli下記コマンドを打ってバージョンが表示されれば成功です。
123vue –version4.1.2プロジェクト用のでディレクトリに移動し、下記コマンドを打ってVueプロジェクトを作成します。
1vue create sample-appManually select featuresを選択
1234567891011Vue CLI v4.1.2┌──────────────────────────────────────────┐│ ││ New version available 4.1.2 → 4.5.13 ││ Run npm i -g @vue/cli to update! ││ │└──────────────────────────────────────────┘? Please pick a preset:default (babel, eslint)❯ Manually select featuresVuexを選択
123456789101112? Please pick a preset: Manually select features? Check the features needed for your project:◉ Babel◯ TypeScript◯ Progressive Web App (PWA) Support◯ Router❯◉ Vuex◯ CSS Pre-processors◉ Linter / Formatter◯ Unit Testing◯ E2E Testing下記コマンドを打ちます。
123cd sample-appnpm run serve下記の表示が出たらブラウザでhttps://smallit.co.jp:8080/にアクセスすると画面が表示されます。
123456App running at:- Local: https://smallit.co.jp:8080/- Network: http://xx.x.xxx.xx:8080/Note that the development build is not optimized.To create a production build, run npm run build. -
StoreでVuexの状態を管理する
Vuexではstoreでデータを管理します。src/store/index.jsの下記の記述でVuexの設定を行っていきます。Storeでの設定はどのコンポーネントからもアクセス可能になります。
※modulesは今回使用しません。1234567export default new Vuex.Store({state: {},mutations: {},actions: {},modules: {},}); - stateで変数を保持する
storeを設定していきます。stateはstoreの基本となるプロパティで、グローバル変数のようにどのコンポーネントからもアクセス可能な変数を定義することができます。
src/store/index.js のstateを書き換えます。12345678export default new Vuex.Store({state: {number: 1},mutations: {},actions: {}});src/App.vueの下記の記述は不要なので削除します。
1<img alt="Vue logo" src="./assets/logo.png" />src/components/HelloWorld.vueを書き換えます。this.$store.state をComputedプロパティに記述してstateにアクセスします。
123456789101112131415<div><p>{{number}}</p></div></template><script>export default {computed:{number(){return this.$store.state.number;}}};</script><style scoped>“1”が表示されます。
- gettersでstateの値を算出する
gettersはVuexで算出プロパティのように使用できます。Computedプロパティのように計算した値を返すような使い方ができます。src/store/index.jsにgettersを追加します。1234567891011export default new Vuex.Store({state: {number: 1},getters: {numberAdd: state => state.number + 10},mutations: {},actions: {}});src/components/HelloWorld.vueを書き換えます。
123456789101112131415161718<template><div><p>{{number}}</p></div></template><script>export default {computed:{number(){return this.$store.getters.numberAdd;}}};</script><style scoped></style>this.$store.gettersでgettersを呼び出すことができます。
”11”が表示されます。$store.state.number+10 のようにしても同じように表示できますが、$store.stateではstateの値を変更できてしまいます。一方gettersでは参照のみですので書き換える心配はありません。Stateの値を参照したいだけの場合は基本的にgettersを使うことが推奨されています。
mutationsでstateの値を更新する -
mutationsでstateの値を更新する
Stateの値を更新したい場合、$store.stateではなくmutationsを使います。$store.stateを使用して更新すると、どこで更新されているか追跡するのが困難になるため、Vuexでstateの更新を行う場合はmutationsで行うのが原則です。src/store/index.jsを書き換えます。
1234567891011121314export default new Vuex.Store({state: {number: 1},getters: {numberAdd: state => state.number + 10},mutations: {incrementNumber(state,num){state.number += num;}},actions: {}});mutationsでは第1引数にstate、第2引数に好きな値をとることができます。今回はインクリメントに使用する数値をとります。
src/components/HelloWorld.vueを書き換えます。
123456789101112131415161718192021222324<template><div><button @click="incrementNumber">+5</button><p>{{number}}</p></div></template><script>export default {computed:{number(){return this.$store.state.number+10;}},methods:{incrementNumber(){this.$store.commit("incrementNumber",5);}}};</script><style scoped></style>MethodsにincrementNumberを定義し、その中でthis.$store.commitと記述することでmutationsを呼び出します。第1引数にmutationsのプロパティ名を、第2引数にmutations のincrementNumberに渡す引数を設定します。
ボタンのクリックイベントにincrementNumberを定義すると、クリックで数値が加算されます -
actionで非同期処理を行う
mutationsでは非同期処理を扱えないため、非同期処理を行たい場合はactionsを使用します。src/store/index.jsを書き換えます。
123456789101112131415161718192021export default new Vuex.Store({state: {number: 1},getters: {numberAdd: state => state.number + 10},mutations: {incrementNumber(state,num){state.number += num;}},actions: {incrementNumber(context,number){setTimeout(() => {context.commit('incrementNumber',number)}, 4000);}}});actionsにincrementNumberを定義します。actionsの第一引数のcontextはcontext.commitと記述してmutationを呼び出したり、context.stateでstateにアクセスできたりします。
今回はsetTimeoutで非同期処理を作り、その中でcontext.commitを記述してmutationのincrementNumberを呼び出します。
src/components/HelloWorld.vueを書き換えます。
123456789101112131415161718192021222324<template><div><button @click="incrementNumber">+5</button><p>{{number}}</p></div></template><script>export default {computed:{number(){return this.$store.state.number+10;}},methods:{incrementNumber(){this.$store.dispatch("incrementNumber",5);}}};</script><style scoped></style>this.$store.dispatchと記述することでactionを呼び出すことができます。
ボタンをクリックすると4秒後に数値が加算され、非同期処理が行われることがわかります。
Vuexの全体像、データフローについて
データフローは下記の図にようになっています。コンポーネントからActionsまたmutationsでstateの値を更新し、図には書かれていないですがgettersを使ってコンポーネントにstateの値を表示するといったフローが基本となります。
【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>