1
1

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 3 years have passed since last update.

Vuexの基本

Last updated at Posted at 2021-08-23

はじめに

Vuexについて勉強したのでまとめてみます。

公式
https://vuex.vuejs.org/ja/

Store

Vuexを使う上でアプリケーションの状態(情報)を管理する役割。

Vuexとは

state management。データ(状態)を管理するもの。
Vuexがない環境ではコンポーネント間のデータの受け渡しには、propsや$emitによるイベントを利用して行います。しかし、コンポーネント間でのデータ受け渡しが頻繁に行われたり階層が増えてくるとporpsやemitでのデータ管理が難しくなる。複雑に構成されたコンポーネントでのデータ管理の難しさを解決するための仕組みがVuexです。Vuexという入れ物にデータを入れることでどのコンポーネントからでもVuex内に保持するデータへのアクセスが可能になります。
Vuexのstateはdataプロパティと同じもの。Vuexのstateにプロパティを追加することですべてのコンポーネントからアクセスが可能となる。Vuexは独立したデータ保管場所。

store\index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  }
})

state→アプリケーションの状態(情報)
getters→stateの一部やstateから返された値を保持する
mutations→stateを更新(変化)させる
action→非同期通信や外部APIとのやりとりを行う

state

stateはdataオプションのような存在で、stateが変更されるとコンポーネントの算出プロパティやテンプレートへと反映されます。なんでもstateに情報を保持させるのではなく、コンポーネント内部でしか使わないようなものはこれまでと同様にdataオプションに、アプリケーション全体で管理するものはstore内で管理すると良いです。

getters

stateから別の値を算出する為に使われる。
gettersは算出プロパティcomputedと同じような働きをしてくれます。
値がキャシュされ、そのgettersが依存しているstateが更新されない限り再評価しません。
違う点は引数にstateと他のgettersを持つことで、それらを使って違う値を返します。
computedと同様に、計算した値を返す以外の処理は行うべきではありません。
computedプロパティだと記述したそのコンポーネント内でしか利用できないので、他のコンポーネントで同じ処理を行いたい場合は同じコードをコンポーネント毎に記述する必要がありまる。でもGettersを利用するとVuexのstoreの中に保存されているので、他のコンポーネントからも同じ方法で利用できます。

getters

store\index.js
  getters: {
  	users : function(state){
  		return state.users.filter(user => user.age < 30);
  	}

computedプロパティ
算出プロパティ(computed)はリアクティブな依存関係にもとづきキャッシュされる.
算出プロパティは、リアクティブな依存関係が更新されたときにだけ再評価されます

component.js
 computed:{
	users: function(){
		return this.$store.state.users.filter(user => user.age < 30);
	}
}

↑2つとも同じ結果になる。

mutations

mutations は state を更新する関数を登録します。
stateの更新を行うためには、mutationsを使う必要があります。
mutations はcommit 関数を使って発火させる。
実際に Vuex のストアの状態を変更できる唯一の方法は、mutationsをコミットすることです。
原則として、mutation以外でstateの更新を行うことを禁止。
commitにはpayloadで値を渡すことができる。

actions

actionsは、状態を変更するのではなく、mutationsをコミットします。
アクションは任意の非同期処理を含むことができます。
mutationsを実行するのはcommitですが、actionsを実行するためにはdispatchメソッドを使用します。


### 例 ```store\index.js import Vue from 'vue'; import Vuex from 'vuex';

Vue.use(Vuex);

export const store = new Vuex.Store({
strict: true,
state: {
products: [
{name: 'Banana', price: 20},
{name: 'Orange', price: 40},
{name: 'Apple', price: 60},
{name: 'Rice', price: 80}
]
},
getters: {
saleProducts: (state) => {
let saleProducts = state.products.map( product => {
return {
name: '' + product.name + '',
price: product.price / 2,
};
});
return saleProducts;
}
},
mutations: {
reducePrice: (state)=> {
state.products.forEach(product => {
product.price -= 1
});
}
},
actions: {
reducePrice: context => {
setTimeout(function(){
//mutationsをコミット
context.commit('reducePrice');
}, 2000);
}
}
});

ビュー

```vue
<template>
    <div id="product-list-one">
        <h2>Product List One</h2>
        <ul>
            <li v-for="product in saleProducts">
                <span class="name">{{ product.name }}</span>
                <span class="price">£{{ product.price }}</span>
            </li>
        </ul>
        <button v-on:click="reducePrice">Reduce Price</button>
    </div>
</template>

メソッドでstateを変更するダメなパターン。使ってはダメ。 strictモードにするとError: [vuex] do not mutate vuex store state outside mutation handlers.のエラーが出る。
<script>
export default {
  computed: {
      saleProducts() {
     //gettersのsaleProductsのデータを取得
      return this.$store.getters.saleProducts
    },
  },
  methods: {
   reducePrice:function(){
     this.$store.state.products.forEach(product => {
       product.price -= 1
     });
   }
  }
}
</script>

メソッドでmutationsをコミットするパターン。

<script>
export default {
  computed: {
      saleProducts() {
      return this.$store.getters.saleProducts
    },
  },
  methods: {
   reducePrice:function(){
   this.$store.commit("reducePrice")
   }
  }
}
</script>

actionsをdispatchするパターン。

<script>
  methods: {
 this.$store.dispatch("reducePrice")
  }
</script>



payloadを使う場合。
store\index.js

  mutations: {
    reducePrice: (state, payload)=> {
      state.products.forEach(product => {
        product.price -= payload
      });
    }
  },
<script>
  methods: {
   reducePrice:function(amount){
    this.$store.commit("reducePrice",amount)
   }
  }
</script>

引数として4を渡す。2ずつ数字が減る。

 <button v-on:click="reducePrice(4)">Reduce Price</button>

同じくpayloadを使う場合。今回はactionsをdispatch。

<script>
  methods: {
   reducePrice:function(amount){
    this.$store.dispatch("reducePrice",amount)
   }
  }
</script>

store\index.js

  mutations: {
    reducePrice: (state, payload)=> {
      state.products.forEach(product => {
        product.price -= payload
      });
    }
  },
  actions: {
    reducePrice: (context) => {
      setTimeout(function(){ 
          context.commit('reducePrice', payload);
      }, 2000);
  }
  }

双方向算出プロパティ

入力された文字に色を変更します。red→赤。blue→青。

色を変えたいタグにstyle属性追加

 :style="{color:$store.state.colorCode}"

v-modelでcolorCodeを指定

   <input v-model='colorCode' type="text">

stateにcolorCode追加

store\index.js
   state: {
    colorCode: 'blue'
  },

mutationsにsetColorCodeメソッド追加

store\index.js
   mutations: {
    setColorCode(state,payload) {
      state.colorCode = payload
    }
  },

computedプロパティでsetColorCodeにペイロードを渡してsetColorCodeメソッドをcommit

<script>
   computed: {
  colorCode: {
    get(){
     return this.$store.state.colorCode
    },
    set(colorValue){
   this.$store.commit('setColorCode',colorValue)
    }
  }
}
<script/>

以上です。
1
1
0

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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?