개발 일기

vuex - module 본문

Client/vue

vuex - module

이건욱

규모가 커지는 과정에 따라서 저장소가 매우 커지게 됩니다.

그러다 보면 저장소를 이제 나누고 싶을 경우가 생기는데 그럴때 사용하는것이 모듈을 통해서 저장소를 나눌 수가 있습니다.

 

각각의 모듈은 state , mutations, actions, getters을 포함 할수가 있습니다.

const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA'의 상태
store.state.b // -> moduleB'의 상태

모듈의 대한 변화와 getter에 내부에서 첫 번째 인자에서는 해당 module에서 가져오게 됩니다.

const moduleA = {
  state: () => ({
    count: 0
  }),
  mutations: {
    increment (state) {
      // state는 지역 모듈 상태 입니다
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    }
  }
}

따라서 액션에서는 다음과같이 루트 상태는 rootState라는 것을 통해서 노출을 합니다.

const moduleA = {
  // ...
  actions: {
    incrementIfOddOnRootSum ({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  }
}

 

예제

/* store.js */
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)


const moduleA = {
    state: {
        count: 1
    },
    getters: {
        get : (state) => {
            return state.count
        } 
    },
    mutations: {
      increment(state) {
        state.count++
      },
      decrement(state) {
        state.count--
      }
    }
}

export default new Vuex.Store({
  modules: {
    a : moduleA
  }
})

/* HelloWorld.vue */

<template>
  <div class="hello">
    <b>count : {{this.count}}</b><br>
    <input type="button" @click="increment()" value="increment"/>
    <input type="button" @click="decrement()" value="decrement"/>
  </div>
</template>

<script>
import { mapMutations, mapGetters } from 'vuex'

export default {
  name: 'HelloWorld',
  computed: {
    ...mapGetters({
      count : 'get'
    })
  },
  methods: {
    ...mapMutations([
      'increment',
      'decrement'
    ]),
  }
}
</script>

<style scoped>
</style>


 

이렇게 했을 때에는 여전히 전역 아래에 등록이 됩니다. 그래서 독립적이거나 재사용되기를 원한다면 namespaced: true라고 명시하면 이제부터는 등록된 모듈의 경로를 기반으로 지정이 됩니다.

/* store.js */
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)


const moduleA = {
    namespaced: true,
    state: {
        count: 1
    },
    mutations: {
      increment(state) {
        state.count++
      },
      decrement(state) {
        state.count--
      }
    }
}

export default new Vuex.Store({
  modules: {
    a : moduleA
  }
})

/* HelloWorld.vue */
export default {
  name: 'HelloWorld',
  computed: {
    ...mapGetters('a' , {
      count : 'get'
    })
  },
  methods: {
    ...mapMutations('a', [
      'increment',
      'decrement'
    ]),
  }
}

위에서 여러 헬퍼를 사용을 했을때 해당 namespace을 찾는것을 볼수가 있는데 저렇게 하는 방법 외에도

import {createNamespacedHelpers} from 'vuex'
const { mapGetters, mapMutations } = createNamespacedHelpers('a')
export default {
  name: 'HelloWorld',
  computed: {
    ...mapGetters({
      count : 'get'
    })
  },
  methods: {
    ...mapMutations([
      'increment',
      'decrement'
    ]),
  }
}

이런식으로도 할수가 있습니다.

 

'Client > vue' 카테고리의 다른 글

Vuex - action ?  (0) 2020.09.15
Vuex ?  (0) 2020.09.15
Vue-router  (0) 2020.09.15
클래스와 스타일 바인딩  (0) 2020.09.14
템플릿 문법  (0) 2020.09.01
Comments