16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【VUEX】ローカルステージに要素を保存、削除する方法【初心者向け】

Last updated at Posted at 2022-09-30

開発環境

MacBook Air (M1, 2020)
vue: "^2.6.14",
yarn 1.22.19

本記事の内容

本記事では、Vue CLIを使用していますが、そのインストール方法に関しては、言及しません。

本記事では以下の内容について記載します。

①stateの値を変更する方法
②ローカルステージに保存する方法
③ローカルステージから削除する方法

準備

  • アプリを作成
  • Vuexのインストール

アプリを作成

上記の内容についてhandson形式で説明するため、まずは簡単なアプリケーションを作成します。
入力したフォームをリスト形式で反映してくれるアプリです。
以下のコードをコピペしてください。

PetView.vue
<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をインストールする。

package.json
"vuex": "^3.6.2",

記載したら、yarn installする。

javascriptファイルの作成

ファイル名はなんでも良いが、ここではstore.jsとしておく。

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に追記

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の値の設置方法

store.js
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するということです。
以下のようなコードを記載してください。

store.js
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を呼ぶための機能として使います。

store.js
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を省略できます。

store.js
export default new Vuex.Store({
    mutations{
        savePet({commit}, pet){
            commit('savePet', pet);
        }
    }
})

vueファイル側からactionsを呼び込む方法

PetView.vue
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からデータを取得するようにします。

store.js
export default new Vuex.Store({
    getters: {
        pets: state => state.pets
    }
}

petsの部分は関数で、引数としてstateをとっています。
今回はデータを加工しないので、取得した値をそのままにしておきます。

加工した値をvueに反映する方法

stateから呼ぶこともできますが、今回はgettersに任せたので、gettersから値を呼び込みましょう。

可読性を高めるために、編集箇所のみを切り抜いて記載しています。

PetView.vue
<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の値を変更することはできるようになりました。
ここからはローカルステージに保存する方法を説明します。

store.js
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で削除の処理を実行

store.js
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を呼び込む

PetView.vue
<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>

終わりに

いかがでしたでしょうか。
次はもっと複雑なアプリも作ってみようと思います!

16
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?