[Vue] Vuex ( state, getter, mapGetters, mapstate)

2022. 11. 2. 22:50Vue

 

 

 

1)state: component의 데이터 역할.

ex) 모든 유저의 수를 불러 오고 싶을때

 

<h1>All Users({{$store.state.allUsers.length}})</h1>

 

2)getter: component의 computed 역할.  코드를 줄여서 작성 가능하다.

  • computed와 다른점.

state를 쓸거라고 ()안에 넣어야한다.

 

store.js

  getters: { //computed
    allUsersCount: function(state) {
      return state.allUsers.length
    }
  },

 

 

Allusers.vue

    <h3>All Users({{$store.getters.countOfSeoul}})</h3>

 

 

아래와 같이 store를 통해 store.js의 긴 코드들을 불러올수 있다.

store.js

  getters: { //computed
    allUsersCount: function(state) {
      return state.allUsers.length
    },
    countOfSeoul: state => {
      let count = 0
      state.allUsers.forEach(user => {
        if(user.address === 'Seoul') count++
      })
      return count;
    },
    percentOfSeoul: (state,getters) => {
      return Math.round(getters.countOfSeoul / getters.allUsersCount *100)
    }
  },

 

3)mapGetters

 

아래 store.getters를 매번 작성하기 귀찮다면 mapGetters를 이용해보자.

 

 

Allusers.vue

    <h1>All Users({{$store.getters.allUsersCount}})</h1>
    <h3>Seoul Users({{$store.getters.countOfSeoul}})({{$store.getters.percentOfSeoul}}%)</h3>

 

  1. script 부분에 mapGetters 선언
import { mapGetters } from 'vuex'

 

 

 

2. export default 부분에 computed 추가 (앞에 … 써주는건 규칙)

    computed: {
      ...mapGetters(['allUsersCount', 'countOfSeoul', 'percentOfSeoul'])
    },

 

 

3. template 부분이 간단하게 써도 잘 작동한다.

    <h1>All Users({{allUsersCount}})</h1>
    <h3>Seoul Users({{countOfSeoul}})({{percentOfSeoul}}%)</h3>

 

 

3-1. 이것도 귀찮다면 다음과 같이 작성한다.

    computed: {
      ...mapGetters({
        count: 'allUsersCount',
        seouls: 'countOfSeoul',
        percent: 'percentOfSeoul'
      })

 

 

template부분이 더 간단해진 것을 볼수 있다.

    <h1>All Users({{count}})</h1>
    <h3>Seoul Users({{seouls}})({{percent}}%)</h3>

 

4)mapstate

 

allusers.vue

  1. script 부분에 mapstate import
import { mapState, mapGetters } from 'vuex'

 

2. computed부분에 mapstate 추가

    computed: {
      ...mapGetters({
        count: 'allUsersCount',
        seouls: 'countOfSeoul',
        percent: 'percentOfSeoul'
      }),
      ...mapState(['allUsers'])
    },

3. 이랬던 코드가

      <v-list-tile 
        v-for="(user, index) in $store.state.allUsers"
        :key="index"
        avatar
      >

4. 다음과 같이 간결해진 것을 볼수 있다.

      <v-list-tile 
        v-for="(user, index) in allUsers"
        :key="index"
        avatar
      >

 

5)mutation: state 값 변화 역할

 

store.js

1.state 사용. payload에 저장하겠다고 addusers 선언

   mutations: {
    addUsers:(state, payload) => {
      state.allUsers.push(payload)
    }
  },

 

 

2.signup.vue에 가서 script 부분에 import하기

import { mapMutations } from 'vuex'

 

 

3. method 부분에 mapmutations 넣기

  export default {
    data() {
      return {
        userId: null,
        password: null,
        name: null,
        address: null,
        src: null
      }
    },
    
    methods: {
      ...mapMutations(['addUsers']),
      }
    }

 

 

4. EventBus.$emit('signUp', userObj) 이부분이

      signUp() {
        let userObj = {
          userId: this.userId,
          password: this.password,
          name: this.name,
          address: this.address,
          src: this.src
        }
        EventBus.$emit('signUp', userObj)
        this.clearForm()
      },

 

 

5. this.addUsers(usersObj)로 대체 가능.

      signUp() {
        let userObj = {
          userId: this.userId,
          password: this.password,
          name: this.name,
          address: this.address,
          src: this.src
        }
        this.addUsers()
        this.clearForm()
      },

userObj인자가 mutation의 payload로 오는 원리로 작동되는 것.

 

 

6)commit: mutation을 일으키는 것을 commit이라고 함.

 

 

store.js

1.아까와 동일하게 mutations 적기

  mutations: {
    addUsers:(state, payload) => {
      state.allUsers.push(payload)
    }
  },

 

 

signup.vue

      signUp() {
        let userObj = {
          userId: this.userId,
          password: this.password,
          name: this.name,
          address: this.address,
          src: this.src
        }
        this.$store.commit('addUsers', userObj)
        // this.addUsers(userObj)
        this.clearForm()
      },

2. adduser라는 mutation을 가져오고 userobj를 payload에 저장.

 

7)actions

 

 

mutation은 비동기 통신에서 문제점을 가지므로 비동기는 actions를 사용한다.

action을 불러올때는 dispatch를 사용한다.

 

store.js

  1. script 부분에 mapaction 선언(import)
import { mapActions } from 'vuex'

2.actions작성

    actions: {
      addUsers: ({ commit }, payload) => { //function({commit})
        commit('addUsers', payload)
      }
  }

3.signup부분에서 actions 사용

=>store.js의 addUsers라는 함수 가져올것이고, userobj를 payload로 넘겨줄거야.

      signUp() {
        let userObj = {
          userId: this.userId,
          password: this.password,
          name: this.name,
          address: this.address,
          src: this.src
        }
        this.$store.dispatch('addUsers', userObj)
      }

4.아래 dispatch 까지 쓰기 번거롭고 함수처럼 사용하고 싶다면 ...mapActions(['addUsers']), 선언해주기.

    methods: {
      ...mapActions(['addUsers']),

      signUp() {
        let userObj = {
          userId: this.userId,
          password: this.password,
          name: this.name,
          address: this.address,
          src: this.src
        }

        this.addUsers(userObj)
        this.clearForm()
},