[TIL] Vue.js/vuex-namedspace : true

JIEUN YANG·2022년 8월 22일
0

vuex에 등록된 modules는 기본적으로 acions, mutations, getters 를 전역 namespace로 관리된다.
따라서 서로 다른 모듈 안에 동일한 네이밍의 actions과 mutation이 존재하면,
이를 실행시켰을 때 각자 다른 모듈임에도 모두 영향을 받아 데이터가 트리거 될 것이다.

특히, 다른 모듈에 동일한 네이밍의 getters가 존재할 때,
그리고 그 모듈들의 namespaced가 전역적으로 설정되어 있을 때 해당 getters를 사용하면 에러를 초래한다. 그 이유는 default : global namespace 로 되어 있기 때문이고 이는 각각의 모듈들의 개별설정을 명시해주지 않는 한 루트경로에 종속되어 있다는 것을 의미한다.

그래서 모듈을 독립적으로 혹은 어떤 경로에서든 재사용하고 싶다면
해당 모듈에 아래 설정을 반드시 표시해줘야 한다.

namespaced: true

// store/lnb.js

const Lnb = {
  // *해당 파일을 모듈화시켜 독립적으로 사용되도록
  namespaced: true,
  state: {
    lnbList: [],
  },
  mutations: {
    setLnbData(state, lnb) {
      state.lnbList = lnb
    },
  },
  actions: {
    getLnbData({ commit }, lnb) {
      commit('setLnbData', lnb)
    },
  },
  getters: {
    lnbList: state => state.lnbList,
  },
}

export default Lnb
  • 모듈이 루트경로에 등록되면 해당 모듈에 정의된 getters, actions, mutations가 namespaced 되고 이는 루트경로가 아닌 해당 모듈 경로를 기반으로 작동됨을 의미한다.
  • 동일한 모듈 내에서는 동일한 getters, actions, mutations을 트리거하고 이때, 경로 명시가 없어도 괜찮다.

만약 namespaced : true 를 명시하지 않는다면, 다른 경로에서 해당 모듈에 트리거 될 때 올바르게 동작하지 않는다.


아래와 같이 lnb모듈의 actions에 접근할 때를 살펴보자.

// store/auth.js

import store from '@/store/index'
import decode from 'jwt-decode'

const Auth = {
  namespaced: true,
  state: {
    userName: '',
    lnbData: [],
  },
  mutations: {
    logIn: (state, { jwtToken, refreshToken }) => {
      const decodedToken = decode(jwtToken)
      state.userName = decodedToken.username

      store.dispatch('Lnb/getLnbData', JSON.stringify(decodedToken.lnbData))
    },
  },
  actions: {},
  getters: {
    userName: state => state.userName,
  },
}

export default Auth
  • actions을 트리거하는 store.dispatch 구문에서 에러가 발생한다.
  • 그 이유는 namespaced : true를 설정하지 않으면 해당 모듈은 global하게 관리되고 이는 '모듈명/트리거명' 이 아닌 '트리거명'으로 접근해야 올바르게 작동함을 의미한다.
  • 따라서 store.dispatch('getLnbData', JSON.stringify(decodedToken.lnbData)) 로 변경해야 한다.



위와 같이 모듈을 독립적으로 사용하지 않는다면 2가지 문제점이 발생할 수 있다.

1. 모든 actions, mutations, getters의 네이밍을 동일하게 사용할 수 없다.

-> 동일 네이밍이 존재한다면 vuex는 어떤 모듈 내에 있는 네이밍을 트리거할지 모르기 때문에 매핑된 모든 트리거를 작동시킨다. 하지만 각기 다른 모듈에서 동일한 테스크를 담당한다면 트리거들의 네이밍은 동일할 수밖에 없는 상황이 발생할 수 있다.

2. 모듈이 많아질수록 네이밍을 확인해야 하기 때문에 코드 작성 시 어려움이 생긴다.

-> 프로젝트의 규모가 클수록 모듈을 분리하여 관리한다. 이는 각각의 모듈을 폴더별로 그룹화 했을 때 구조가 더 클린하고 소스 코드가 잘 정리된 느낌을 줄 수 있기 때문이다. 하지만 아래처럼 모듈이 2개 아닌 20개,,200개가 된다면 어떨까?
트리거를 네이밍 할때마다 나머지 모듈에 해당 네이밍이 존재하는지 아닌지 확인해야 하는 번거로움이 있다.

1. module : A // 장바구니 모듈
const A {
state : {
	items : []
},
actions : {},
mutations : {
	saveList(state, items){ // ** 다른 모듈에 해당 네이밍이 있는지 확인 필요
    	state.items = items
    }
},
getters : {}
}




2. module : B // 위시리스트 모듈
const B {
state : {
	items : []
},
actions : {},
mutations : {
	saveList(state, items){  // A 모듈에 이미 네이밍 되었기 떄문에 다른 메서드명으로 변경 필요
    	state.items = items
    }
},
getters : {}
}

.
.
.
.
.


따라서, 모듈을 독립적으로 관리한다는 것의 의미는

1. 모듈에 트리거 할 때, 해당 경로를 명시하여 직관적으로 코드를 확인할 수 있고

store.dispatch('Lnb/getLnbData')
-> Lnb모듈 내에 actions를 실행시켜라!

2. 네이밍이 동일할 때 발생할 수 있는 모듈의 충돌과 데이터 흐름을 방지한다.

store.dispatch('saveList')
-> 'saveList' 네이밍을 사용하는 모듈이 전체에서 딱 1개라면 괜찮지만 아닐 때에는
vuex 입장에서 도대체 어떤 모듈의 'saveList'를 실행하라는 건지 알 수 없다.

profile
violet's development note

0개의 댓글