16. Vue JS/Vue 2

16. Vue 2 - Vuex Module 분리하기

THE HEYDAZE 2021. 4. 20. 16:22
  OS   Windows 10 PRO 64bit 버전 20H2 (OS 빌드 19042.867)
  Vue   2.5.13

 

코드
 

sout1217/TIL2021

Contribute to sout1217/TIL2021 development by creating an account on GitHub.

github.com

 

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

Vue.use(Vuex)

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

어플리케이션의 규모가 커질수록 data 를 하나의 store 안에 작성하는 것은 유지보수하기가 힘들어진다

때문에 vuex 에서는 module 로 분리하여 관리할 수 있도록 지원한다.

 

모듈 디렉토리와 모듈들을 생성

설명을 위해 account 와 auth 라는 명을 사용했습니다

modules/account.js
const account = {
  namespaced: true,
  state: {
    name: 'martin',
    age: 10,
    gender: 'male',
    job: 'doctor',
    email: 'martin@gmail.com',
    phoneNumber: '010-1111-2222',
  },
  getters: {
    GET_NAME: state => state.name,
    GET_EMAIL: state => state.email,
    GET_PHONE_NUMBER: state => state.phoneNumber,
  },
};

export default account;

 

modules/auth.js
const auth = {
  namespaced: true,
  state: {
    token:
      'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
    client: 'Chrome',
  },
};

export default auth;

 

store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import account from './modules/account';
import auth from './modules/auth';

Vue.use(Vuex);

export default new Vuex.Store({
  strict: true,
  modules: {
    account,
    auth,
  },
});

 

views/HomePage.vue
<template>
  <div>
    <h1>home page</h1>

    <h2>longStateName : {{ longStateName }}</h2>
    <h2>shortStateName : {{ shortStateName }}</h2>
    <h2>longGettersName : {{ longGettersName }}</h2>
    <h2>shortGettersName : {{ GET_NAME }}</h2>

    <hr />

    <h2>auth module token : {{ token }}</h2>
    <h2>auth module client : {{ client }}</h2>

    <hr />
    <h2>namespaceEmail : {{ namespaceEmail }}</h2>
    <h2>GET_PHONE_NUMBER : {{ GET_PHONE_NUMBER }}</h2>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex';
export default {
  name: 'HomePage',
  computed: {
    ...mapState({
      longStateName(state) {
        return state.account.name;
      },
    }),
    ...mapState({
      shortStateName: state => state.account.name,
    }),
    ...mapGetters({
      longGettersName: 'GET_NAME',
    }),
    ...mapGetters(['GET_NAME']),

    ...mapState({
      token: state => state.auth.token,
      client: state => state.auth.client,
    }),

    ...mapGetters({
      namespaceEmail: 'GET_EMAIL',
    }),

    ...mapGetters(['GET_PHONE_NUMBER']),
  },
};
</script>

<style scoped></style>

 

결과

 

namespaced 사용하기

namespaced 를 true로 설정하는 경우 앞에 사용 할 때는 모듈명을 붙여주어야 한다 - '모듈명/겟터명'

<template>
  <div>
    <h1>home page</h1>

    <h2>longStateName : {{ longStateName }}</h2>
    <h2>shortStateName : {{ shortStateName }}</h2>
    <h2>longGettersName : {{ longGettersName }}</h2>
    <h2>shortGettersName : {{ GET_NAME }}</h2>

    <hr />

    <h2>auth module token : {{ token }}</h2>
    <h2>auth module client : {{ client }}</h2>

    <hr />
    <h2>namespaceEmail : {{ namespaceEmail }}</h2>
    <h2>GET_PHONE_NUMBER : {{ GET_PHONE_NUMBER }}</h2>
  </div>
</template>

<script>
import { mapState, mapGetters } from 'vuex';
export default {
  name: 'HomePage',
  computed: {
    ...mapState({
      longStateName(state) {
        return state.account.name;
      },
    }),
    ...mapState({
      shortStateName: state => state.account.name,
    }),
    ...mapGetters({
      longGettersName: 'account/GET_NAME',
    }),
    ...mapGetters(['account/GET_NAME']),

    ...mapState({
      token: state => state.auth.token,
      client: state => state.auth.client,
    }),

    ...mapGetters({
      namespaceEmail: 'account/GET_EMAIL',
    }),

    ...mapGetters(['account/GET_PHONE_NUMBER']),
  },
};
</script>

<style scoped></style>

단점은 겟터명 그대로 불러올 때 computed 명을 지정해주어 한다 (필자는 computed를 지정 안하고 설정하는 방법을 모름)

위에서는 ...mapGetters(['account/GET_NAME']) 과 ...mapGetters(['account/GET_PHONE_NUMBER]) 가 해당된다

 

결과 ( 2개가 화면에 출력되지 않는 모습 - account/GET_NAME 으로 써도 안나옵니다 )

 

키워드 자동완성
namespace 가 true 인 경우

자동완성 

namespace가 false 인 경우

자동완성

 

추가 설명

modules 디렉토리에 index.js 를 만들어 modules 자체를 import 하는 방법도 있다

 

공식홈에 가면 모듈에 모듈을 중첩하는 방식도 알려준다.

 

모듈 | Vuex

모듈 단일 상태 트리를 사용하기 때문에 애플리케이션의 모든 상태가 하나의 큰 객체 안에 포함됩니다. 그러나 규모가 커짐에 따라 저장소는 매우 비대해질 수 있습니다. 이를 위해 Vuex는 저장

vuex.vuejs.org