![見出し画像](https://assets.st-note.com/production/uploads/images/74504311/rectangle_large_type_2_bcd8ad686f775a0b6ea8231614249043.png?width=800)
Vue.js勉強記録その26 Vue3を更にパワーアップしよう 5-3 ver1
こちらの書籍で勉強中です。
今回は、vuexというものを使います。どうやら、データを格納しておくことのできる場所のようです。
■Vuexによる状態管理
・Vuexのインストール
まず、Vuexをインストールしていきます。CDNで読み込むことも出来るらしいけど、今回はnpmを使ってインストールしていきます。
npm install vuex@next
・Vuexの基本
Vuexは、「ストア」と呼ばれる物を使ってデータを管理します。そのためには、それ専用のファイルを作る必要があります。
また、各コンポーネントからストアへアクセスし値を取得するには、$storeという、Vuexのオブジェクトを使います。
・使ってみる
srcフォルダの中に、store.jsを作り、以下のように記述します。
import { createStore } from 'vuex'
export const store = createStore({
state() {
return {
message: 'This is store data.'
}
}
})
まずは、importを使ってvuexからcreateStore関数を読み込みます。その後、その関数を使っていきます。使い方は、以下のような感じです。
export const store = createStore(引数)
引数には、ストアに関する情報が入ります。そしてそれを定数に代入し、そのままexportすることで、外部からアクセス出来るようにしています。
引数には、オブジェクトが入るのですが、まずstateというメソッドを用意します。その中で、必要なデータをオブジェクトの形で書き、returnしてあげます。
今回は、{message: 'This is store data.'}を用意しています。
では、messageをコンポーネント側で利用してみます。
まずは、main.jsを書き換えます。
import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
import { store } from './store.js'
createApp(App).use(store).mount('#app')
store.jsをimportします。さらに、mountする前に、use(store)で、storeを使えるようにします。
次にApp.vueを書き換えます。
<template>
<HelloWorld />
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
};
</script>
HelloWorldを出力するだけのシンプルな形になっています。
HelloWorld.vueを書き換えます。
<template>
<div class="alert alert-primary">
<h1>{{ data.title }}</h1>
<p class="mt-3 h5">{{ $store.state.message }}</p>
</div>
</template>
<script>
import { ref, reactive } from "vue";
export default {
setup(props) {
const data = reactive({
title: "Vuex",
});
return { data };
},
};
</script>
<p class="mt-3 h5">{{ $store.state.message }}</p>
この部分で、messageを出力しています。
$storeが、ストアに保管された値がまとめられているオブジェクトで、その中のstateにある、messageを取り出しています。
ブラウザで見るとこんな感じです。
■ストアの中のステートの値を操作する
直接$store.stateの値を書き換えるのは、推奨されていないらしく、ミューテーションと呼ばれる、値を操作するための処理を用意する。
mutations:{
名前:(引数)=>{
処理内容
},
・・・必要なだけ用意・・
}
こんな感じの書き方です。
store.js
import { createStore } from 'vuex'
export const store = createStore({
state() {
return {
message: 'This is store data.',
counter: 0
}
},
mutations: {
count: (state) => {
state.counter++;
},
reset: (state) => {
state.counter = 0;
}
}
})
countとresetというミューテーションを用意します。
各々、stateのcounterの値を変更する記述が書かれています。
コンポーネント側でミューテーションにアクセスするには、
$store.commit('名前')
こんな感じでアクセスします。
HelloWorld.vue
<template>
<div class="alert alert-primary">
<h1>{{ data.title }}</h1>
<p class="mt-3 h5">{{ $store.state.message }}</p>
<hr />
<div
class="btn btn-secondary"
@click="$store.commit('count')"
@click.shift="$store.commit('reset')"
>
<a class="h5"> clicked:{{ $store.state.counter }} </a>
</div>
</div>
</template>
<script>
import { ref, reactive } from "vue";
export default {
setup(props) {
const data = reactive({
title: "Vuex",
});
return { data };
},
};
</script>
<div class="btn btn-secondary"
@click="$store.commit('count')"
@click.shift="$store.commit('reset')"
>く
クリックするとcountを呼び出し、shiftキーを押しながらクリックするとresetを呼び出します。
なお、@clickは、v-on:clickと同じ意味です。
ブラウザで見ると、ボタンを押すと数字が増えていき、shiftキーを押しながらクリックすると0に戻ります。
・ミューテーションに引数を渡す
ミューテーションに引数を渡すことも出来ます。
store.js
import { createStore } from 'vuex'
export const store = createStore({
state() {
return {
message: 'This is store data.',
counter: 0
}
},
mutations: {
count: (state, n) => {
state.counter += n;
},
reset: (state) => {
state.counter = 0;
}
}
})
countの所を以下のように直しています。
count: (state, n) => {
state.counter += n;
},
HelloWorld.vue
<template>
<div class="alert alert-primary">
<h1>{{ data.title }}</h1>
<p class="mt-3 h5">{{ $store.state.message }}</p>
<hr />
<div
class="btn btn-secondary w-100"
@click.exact="$store.commit('count', 1)"
@click.shift="$store.commit('count', 2)"
@click.alt="$store.commit('count', 3)"
>
<a
class="h5 text-white text-decoration-none"
@click.stop="$store.commit('reset')"
>
clicked:{{ $store.state.counter }}
</a>
</div>
</div>
</template>
<script>
import { ref, reactive } from "vue";
export default {
setup(props) {
const data = reactive({
title: "Vuex",
});
return { data };
},
};
</script>
クリックイベントを追加します。
<div class="btn btn-secondary w-100"
@click.exact="$store.commit('count', 1)"
@click.shift="$store.commit('count', 2)"
@click.alt="$store.commit('count', 3)"
>
何も押さずにクリックすると1を、
shiftを押しながらクリックすると2を、
altを押しながらクリックすると3を、ミューテーションに渡しています。
こんな感じに値を渡します。
■まとめ
今回は、ストアに関してでした。今のところ、複数のコンポーネントで共通の値を保持したいときとかに使うのかな?という認識です。
もうちょっとVuexは続きます。
この記事が気に入ったらサポートをしてみませんか?