Vuex – 상태 관리 패턴(Store)을 활용해 보자

vuex는 복잡도가 높은 앱에서 props, event emit을 통한 상태관리를 보다 쉽게 하기 위해서 사용합니다.
중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있습니다.
주로 로그인 이름, 사이드바 노출여부, 이전 페이지 주소 등을 저장하는데 쓰입니다.

설치

npm install vuex --save

state, getters, mutations, actions

  • state : 상태 관리를 할 데이터
  • getters : 상태 관리 중인 데이터를 가져옴 / computed에 등록
  • mutations : 상태 관리 중인 데이터를 변경 / methods에 등록
  • actions : 상태 관리 중인 데이터를 변경(비동기) / methods에 등록

1.구조

- store
  : index.js
- components
  : child.vue
app.vue
main.js

2.store/index.js

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

// vuex 주입
Vue.use(Vuex)

const store = new Vuex.Store({
    // state 선언
    state : {
        counter : 0
    },
    getters : {
        getCounter(state) {
            return state.counter;
        }
    },
    mutations : {
        addCountet(state) {
            return state.counter++;
        },
        subCounter(state) {
            return state.counter--;
        }
    },
    actions : {
        addCounter(state) {
            return  context.commit('addCounter');
        }
    }
})

export default store

3.App.vue

<template>
    <div id="app">
        {{ parentCountet }}
        <button @click="addCounter">+</button>
        <button @click="subCounter">-</button>

        <child></child>
    </div>
</template>

<script>
import Child from './components/child'

export default {
    name : 'App',
    methods : {
        ...mapMutations({
            subCounter : 'subCounter'
        }),
        ...mapActions({
            addCounter : 'addCounter'
        })
    },
    computed : {
        ...mapGetters({
            parentCounter : 'getCounter'
        })
    },
    components : {
        'child' : Child
    }
}
</script>

4.components/child.vue

<template>
    <div>
        Child Counter : {{ childCounter }}
    </div>
</template>

<script>
import { mapGetterse } from 'vuex'

export default {
    computed : {
        ...mapGetters({
            childCounter : 'getCounter'
        })
    }
}
</script>

5.기타

mapMutaions에 인자 값 넘기기

methods : {
    addCounter() {  
        this.$store.commit('addCounter'); // 일반
        this.$store.commit('addCounter',10); // 특정 값 전달
        this.$store.commit('addCounter', { 
            value : 10,
            arr : [1,2,3,4]
        })
    }
}
mutations : {
    addCounter : function (state, payload) {
        state.counter = payload.value;
    }
}

app, vuex의 메소드명이 동일한 경우

methods : {
    ...mapMutations({
        'addCounter' // a
    })
}

actions 등록

actions : {
    addCounter : function (context) {
        // vuex의 addCounter 메소드
        return context.commit('addCounter');
    }
}

actions 사용

methods : {
    addCounter() {
        this.$store.dispatch('addCounter');
    }
}

…문법 – babel 필요

computed: mapGetters([
    'getCounter'
]),
computed: {
    ...mapGetters([
        'getCounter'
    ])
}