상세 컨텐츠

본문 제목

Vuex

Vue

by 일단두잇 2023. 1. 22. 14:42

본문

반응형

"Vuex는 Vue.js 상태관리 패턴 입니다."

사실 모든 SPA 프로젝트에서는 상태관리 패턴을 기본으로 사용중이거나 고려중일 것입니다.

 

사용을 고려하는 이유들은 간단히 보면 아래와 비슷합니다.

 

1. 각 Components 간의 데이터를 공유하고 처리 가능

 

2. 화면 구현과 이터 처리하는 로직을 구분함으로서 유지보수가 용이


1. 설치

npm i --save vuex@next
 

2. Vuex 구조

namespaced를 사용하여 아래와 같이 각 업무 별로 구분해준다.

 

3. vuex 사용 :

 

Namespaced를 사용할 경우

실제 vuex를 사용하고자 하는 component에서 아래와 같이 사용한다.

createNamespacedHelpers(moduleName)

 

그런데 이 경우 moduleName이 정확해야한다.

moduleName : 자신의 module Path + 생성시 정한 Name

 

예를 들어 아래 toast는 common 하위이므로

Path : common/

Name : toast

즉, ModuleName은 common/toast 이다.

 

index.js

import { createStore } from 'vuex'

import { module as common } from './modules/common/commonStore'
import { module as main } from './modules/main/mainStore'

export default createStore({
  modules: {
    common,
    main
  }
})
 

 

modules/common/index.js

하위 vuex 모듈을 등록한다.

import { module as toast } from './toastStore'

const ModuleName = 'common' // 반드시 초기 Store 생성시 정한 path/Name과 동일해야합니다.
const module = {
  namespaced: true,
  modules: {    
    toast    
  }
}

export {
  module,
  ModuleName
}
 

실제 사용하는 vuex 정의

modules/main/mainStore.js

const ModuleName = 'main' // 반드시 초기 Store 생성시 정한 path/Name과 동일해야합니다.
const module = {
  namespaced: true,
  state: {
    menuList: []
  },
  getters: {
    menuList (state) {
      return state.menuList
    }
  },
  actions: {
    setMenuList ({ commit, state }, menuList) {
      commit('setMenuList', menuList)
    }
  },
  mutations: {
    // 화면에 노출될 GNB 카테고리 저장
    setMenuList(state, menuList) {
      state.menuList = menuList
    }
  },
  modules: {    
    // 하위 모듈 Vuex 정의
  }
}

export {
  module,
  ModuleName
}
 

modules/common/toastStore.js

const ModuleName = 'common/toast' // 반드시 초기 Store 생성시 정한 path/Name과 동일해야합니다.
const module = {
  namespaced: true,
  state: {
    visible: false,
    message: '',
    timer: null,
    duration: 2000,
    onClose: null
  },
  actions: {
    showToast ({ state }, option) {
      state.message = ''
      state.onClose = null
      state.visible = true
      if(typeof option === 'object') {
        state.message = option.message
        if (typeof option.onClose === 'function') {
          state.onClose = option.onClose
        }
      }else{
        state.message = option
      }
      state.timer = setTimeout(() => {
        module.actions.hideToast({ state: state })
      }, state.duration)
    },
    hideToast({ state }) {
      clearTimeout(state.timer)
      state.visible = false
      state.onClose && (typeof state.onClose === 'function') && state.onClose()
    }
  }
}

export {
  module,
  ModuleName
}
 

4. Component에서 Vuex 사용

import { ModuleName as toastName } from '@store/common/toastStore'
import { ModuleName as mainName } from '@store/main/mainStore'
import { createNamespacedHelpers } from 'vuex'
const { mapGetters, mapActions } = createNamespacedHelpers(toastName)
// or
// vuex를 여러개 사용할때 아래와 같이 다르게 접근 가능
const toastStore = createNamespacedHelpers(toastName)
const mainStore = createNamespacedHelpers(mainName)

export default {
  data() {
    return {
      text: ''
    }
  },
  computed: {
    // vuex getters computed로 정의
    ...mapGetters([]),
    ...toastStore.mapGetters([]),
    ...mainStore.mapGetters(['menuList'])
  },
  created() {
    this.setMenuList(['HOME', 'MENU1', 'MENU2']) 
    console.log('menuList : ', this.menuList)
  },
  methods: {
    // vuex actions를 method로 정의
    ...mapActions([]),
    ...toastStore.mapActions([]),
    ...mainStore.mapActions(['setMenuList'])   
  }
}
 

 

 


 

 

 

반응형

'Vue' 카테고리의 다른 글

컴포넌트 import 없이 사용하기 - 전역등록  (0) 2023.01.22
Vue Router v4.x  (0) 2023.01.22
Vue Application Package 구조  (0) 2023.01.22
Vue Component 쉽게 debug 하기  (0) 2023.01.22
eslint 적용 - vue3  (0) 2023.01.22

관련글 더보기

댓글 영역