開発環境
MacBook Air (M1, 2020)
vue: "^2.6.14",
yarn 1.22.19
本記事の内容
本記事では、Vue CLIを使用していますが、そのインストール方法に関しては、言及しません。
本記事では以下の内容について記載します。
①stateの値を変更する方法
②ローカルステージに保存する方法
③ローカルステージから削除する方法
準備
- アプリを作成
- Vuexのインストール
アプリを作成
上記の内容についてhandson形式で説明するため、まずは簡単なアプリケーションを作成します。
入力したフォームをリスト形式で反映してくれるアプリです。
以下のコードをコピペしてください。
<template>
<div>
<label for="name">Name</label><br>
<!--inputした内容でvueインスタンスの内容を更新したいため、v-modelを使用する-->
<input id="name" type="text" v-model="name"><br>
<label for="age">Age</label><br>
<input id="age" type="number" v-model="age"><br>
<label for="birthday">Birthday</label><br>
<input id="birthday" type="date" v-model="birthday"><br>
<!--ボタンをクリックしたら、上記に入力した内容を配列にpushさせる。
<button @click="savePet">ADD</button>
<hr />
<table>
<thead>
<th>Name</th>
<th>Age</th>
<th>Birthday</th>
</thead>
<tbody>
<!--配列に関しては、stateから取得してくる必要がある。これから説明するため、あえて空欄にしておく。-->
<tr v-for="(pet, index) in " :key="index">
<td>{{pet.name}}</td>
<td>{{pet.age}}</td>
<td>{{pet.birthday}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default{
name:"PetView",
//pushしたい内容を定義。push先の配列は、stateで管理するため、記載しない。
data: function() {
return {
//inputで入力した値がここに入る。
name:"",
age:null,
birthday:""
}
},
methods: {
savePet: function() {
const pet = {
//thisを使用することで、vueインスタンスのプロパティにアクセス。
name: this.name,
age: this.age,
birthday: this.birthday,
}
}
}
}
</script>
Vuexをインストール
手順は以下です。
- インストール
- javascriptファイルの作成
- main.jsに追記
Vuexをインストールする。
"vuex": "^3.6.2",
記載したら、yarn installする。
javascriptファイルの作成
ファイル名はなんでも良いが、ここではstore.jsとしておく。
import Vue from 'vue'
import Vuex from 'vuex'
//Vuexの使用を宣言
Vue.use(Vuex)
//全体で使えるように、export
export default new Vuex.Store({
//このVue.jsのプロジェクト全体で使えるグローバル変数を表す。
state: {
},
//グローバル変数を加工する算出プロパティ。stateを加工する際はここで行う。
getters: {
},
//stateの値を変更することを許された唯一の機能。
mutations: {
},
//mutationが同期処理しかできないため、非同期処理を行う機能。しかし、予測可能性を高めるため、ここでは、mutationを呼ぶ際に使う。
actions: {
}
})
main.jsに追記
import Vue from 'vue'
import App from './App.vue'
import store from './store/index';//追記
Vue.config.productionTip = false
new Vue({
store,//追記
render: h => h(App),
}).$mount('#app')
ローカルステージに保存する方法
ローカルステージに保存する方法の前に、stateというグローバル変数に値を保存、変更する方法について解説します。
①stateの値の設置方法
②mutationsでstateの値を変更する方法
③actionsでmutationsを実行する方法
④vueファイル側からactionsを呼び込む方法
⑤gettersで値を加工する方法
⑥加工した値をvueに反映する方法
順に説明していきます。
stateの値の設置方法
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
pets:[] //追記
},
getters: {
},
mutations: {
},
actions: {
}
})
stateには基本的に全体で管理したい情報を設置します。
自分の場合はpetsという配列を管理したかったので、このような値を設置しました。
mutationsでstateの値を変更する方法
mutationsとはstateの値の変更を許された唯一の機能です。
methodsの方でstateの値を変更することはできるのですが、コードの可読性を上げるために、そう決めます。
今回自分が行いたいのは、petsという配列にフォームで入力した値をpushするということです。
以下のようなコードを記載してください。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
pets:[] //追記
},
getters: {
},
mutations: {
},
actions: {
}
①stateの状態を変更したいので、第一引数にはstate,第二引数には先ほどPetView.vueファイルで定義したpetを取ります。
ちなみに第二引数に複数の引数を与えたい場合は、オブジェクトの形で与えてあげます。
②stateのオブジェクトの中のpetsという配列を取りたいので、このように書きます。
actionsでmutationsを実行する方法
mutationsに行いたい処理を書いただけでは実行されません。
その実行を指示する必要があります。
そこで登場するのがactionsです。
しかし、このactions、非同期処理を行うための機能であり、今回のような同期処理を実行させたい場合、使う必要がありません。
しかし、理解度を上げるため、かつコードの可読性を高めるため、actionsをmutationsを呼ぶための機能として使います。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
pets:[] //追記
},
getters: {
},
mutations: {
//以下①で説明
savePet(state, pet) {
//以下②で説明
state.pets.push(pet)
},
},
actions: {
}
①第一引数としてはcontextを取ります。
contextにはいろんなものが入っています。commit,state,dispatchなどです。
しかし、ここではactionsはmutationsを呼ぶものとして決めましたので、commitを選択します。
②commitを書くことで、mutationsに定めた処理を実行させることができます。
引数はmutationsに与えたい引数を与えてあげます。
ちなみに余談ですが、このように書くことで、contextを省略できます。
export default new Vuex.Store({
mutations{
savePet({commit}, pet){
commit('savePet', pet);
}
}
})
vueファイル側からactionsを呼び込む方法
methods: {
savePet: function() {
const pet = {
name: this.name,
age: this.age,
birthday: this.birthday,
}
//追記
this.$store.dispatch('savePet', pet)
},
},
追記コードに関しては、こういうものと覚えてください。
actionsを呼ぶ場合は、dispatchになりますが、mutationsを呼ぶ場合は、$storeまではそのままで、commitとなります。
gettersで値を加工する方法
変更された値をさらに加工したい場合に、使用する機能です。
今回のようにデータを加工する必要がない場合に使う必要はありませんが、今回は理解度を高めるため、あえて、gettersからデータを取得するようにします。
export default new Vuex.Store({
getters: {
pets: state => state.pets
}
}
petsの部分は関数で、引数としてstateをとっています。
今回はデータを加工しないので、取得した値をそのままにしておきます。
加工した値をvueに反映する方法
stateから呼ぶこともできますが、今回はgettersに任せたので、gettersから値を呼び込みましょう。
可読性を高めるために、編集箇所のみを切り抜いて記載しています。
<template>
<table>
<thead>
<th>Name</th>
<th>Age</th>
<th>Birthday</th>
</thead>
<tbody>
<!--computedで定義した関数からv-forで値を一つずつ取り出す。-->
<tr v-for="(pet, index) in arrayPets" :key="index">
<td>{{pet.name}}</td>
<td>{{pet.age}}</td>
<td>{{pet.birthday}}</td>
</tr>
</tbody>
</table>
</template>
<script>
computed:{
arrayPets(){
//petsの部分にはgettersで定義した関数を入れる。
return this.$store.getters.pets
}
}
</script>
無事入力した値が反映されていれば成功です。
ちなみに、stateから値を取りたい場合は、gettersをstateに変更すれば取得できます。
ローカルステージに保存する方法
さて、ここまでで、stateの値を変更することはできるようになりました。
ここからはローカルステージに保存する方法を説明します。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//追記
//localStorageに保存したリストを取得
const savedPets = localStorage.getItem('practice')
//編集
const store = new Vuex.Store({
//編集
//localStorageに保存されたリストがあれば取得、なければ空の配列を返す。
state: {
pets: savedPets ? JSON.parse(savedPets): []
},
getters: {
pets: state => state.pets
},
mutations: {
savePet(state, pet) {
state.pets.push(pet)
}
},
actions: {
savePet({commit}, pet){
commit('savePet', pet);
}
}
})
//追記
//subscribeはストアのインスタンスメソッドで、全てのmutationの後に呼ばれる。
store.subscribe((mutation, state) => {
//データの状態を更新後にlocalStorageへデータの状態を保存
localStorage.setItem('practice', JSON.stringify(state.pets))
})
//追記
//main.jsでインポートできるように設定
export default store
ローカルステージから削除する方法
ボタンを押したら押したテーブルが削除される実装行います。
- mutationsとactionsで削除の処理を実行
- vueファイル側でactionsを呼び込む
mutationsとactionsで削除の処理を実行
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const savedPets = localStorage.getItem('simple-app')
const store = new Vuex.Store({
state: {
pets: savedPets ? JSON.parse(savedPets): []
},
getters: {
pets: state => state.pets
},
mutations: {
//indexの要素を一つ削除する処理を記載。
deletePet(state, index) {
state.pets.splice(index, 1)
}
},
actions:{
deletePet({commit}, index){
commit('deletePet', index);
}
}
})
store.subscribe((mutation, state) => {
localStorage.setItem('simple-app', JSON.stringify(state.pets))
})
export default store
vueファイル側でactionsを呼び込む
<template>
<tbody>
<tr v-for="(pet, index) in arrayPets" :key="index">
<td>{{pet.name}}</td>
<td>{{pet.age}}</td>
<td>{{pet.birthday}}</td>
//追記
ボタンを押した要素のインデックスのデータを渡してあげる。
<button @click="deletePet(index)">X</button>
</tr>
</tbody>
</template>
<script>
methods:{
deletePet: function(index) {
if(confirm('本当にこのリストを削除しますか?')){
//actionsで定義した名前を記載し、actionsを呼び込む
this.$store.dispatch('deletePet', index)
}
},
}
</script>
終わりに
いかがでしたでしょうか。
次はもっと複雑なアプリも作ってみようと思います!