반응형
Vuex
Vue.js 어플리케이션을 개발하면서 여러 상태 값을 사용하거나, 여러 컴포넌트 간의 공유 상태 공유를 하게 되면 상태 관리가 어려워지고, 상태 변경 추적도 어려워집니다. 이때 Vuex 라이브러리를 사용하면 복잡한 상태를 중앙 집중식으로 관리하여 효율적으로 상태 관리할 수 있게 도와줍니다.
Vue.js에서 컴포넌트는 [부모-자식] 관계를 갖기 때문에 props를 통해 데이터를 주고받지만, Vuex를 통해 따로 빼놓음으로 데이터를 중앙 집중식으로 관리하기 때문에 [부모-자식] 관계에 얽매이지 않을 수 있습니다. 물론 Event Bus를 사용하면 이 역시 [부모-자식] 관계에 얽매이지 않을 수 있지만 어플리케이션의 볼륨이 커질수록 관리가 어려워지기 때문에 규모가 큰 경우 Vuex를 사용합니다.
💁♂️ Vuex 설치 방법
npm:
npm install vuex --save
yarn:
yarn add vuex
Vuex 사용 구조
- State:
State는 Vuex 스토어에 저장되는 애플리케이션의 상태 데이터를 나타냅니다. 모든 컴포넌트에서 상태 데이터에 접근할 수 있고, 중앙 집중식으로 관리되기 때문에 데이터의 일관성과 관리가 용이합니다. State는 직접 수정하지 않고 오직 `Mutations`을 통해 변경해야 합니다. - Mutations:
Mutations은 State를 동기적으로 변경하기 위해 사용되는 메서드입니다. State의 값을 변경하거나 조작하는 로직이 담기며, 뮤테이션은 순차적으로 호출되어 상태를 변화시킵니다. 다른 컴포넌트에서 `commit('함수명', '인자')`로 호출합니다. - Actions:
Actions는 비동기적인 작업을 처리하기 위해 사용되는 메서드입니다. 비동기 작업을 수행하고, 그 결과에 따라 Mutations를 호출하여 State를 변경합니다. 서버와의 통신이나 비동기적인 작업은 Actions에서 처리하며, 필요에 따라 비동기 처리 결과를 컴포넌트에 반환할 수 있습니다.다른 컴포넌트에서 `dispatch(`함수명`,`전달인자`)로 호출합니다. - Getters:
Getters는 State의 값을 가공하여 필요한 형태로 반환하는 메서드입니다. Vuex 스토어에 저장된 State 데이터를 컴포넌트에서 사용하기 전에 가공하거나 계산할 때 유용합니다.
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store(
{
state: {
count: 0,
},
mutations: {
INCREMENT(state, amount) {
state.count += amount
},
DECREMENT(state, amount) {
state.count -= amount
},
SETTING(state, amount) {
state.count = amount
},
},
actions: {
setCount({ commit }, amount) {
commit('SETTING', amount); // 'SETTING' 뮤테이션 호출
},
incrementAsync({ commit }, amount) {
setTimeout(() => {
commit('INCREMENT', amount);
}, 1000);
},
},
getters: {
getCount: (state) => {
return state.count;
},
getDoubleCount: (state) => {
return state.count * 2;
},
}
}
);
export default store;
- `state`: 상태값을 저장하는 객체로, `count`라는 상태를 정의하고 초기값이 0으로 설정되어 있습니다.
- `mutations`: `state`(상태값)을 변경하기 위한 메서드를 정의합니다.
- `actions`: 비동기적인 작업을 처리하기 위해 사용되는메서드들을 정의합니다. 각각은 `commit`을 통해 mutations을호출하여 상태값을 변경합니다.
- `getters`: `state`(상태값)를 가공하여 필요한 형태로 반환하는 메서드를 정의합니다.
다른 컴포넌트에서 각각의 기능에 접근하기 위해서 다음과 같은 문법을 적용하면 됩니다.
- `this.$store.state`
- `this.$store.commit`
- `this.$store.dispatch`
- `this.$store.getters`
💁♂️ Vuex Store를 전역으로 사용하기 위해서는 Vue 어플리케이션에서 Vuex Store를 생성하고 전역으로 등록해야 합니다. 전역으로 등록하게 되면 모든 컴포넌트에서 `this.$store`를 통해 Vuex Store에 접근할 수 있습니다.
Vue 어플리케이션의 진입점인 `main.js` 파일에 전역으로 등록하는 것이 일반적입니다.
main.js:
import Vue from 'vue'; import App from './App.vue'; import store from './store'; // Vuex 스토어를 import Vue.config.productionTip = false; new Vue({ store, // Vuex 스토어를 전역으로 등록 render: (h) => h(App), }).$mount('#app');
Vuex 모듈화
store.js:
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import todoModule from './modules/todoModule';
import userModule from './modules/userModule';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
todoModule,
userModule, // userModule 모듈 등록
},
});
todoModule.js:
// store/modules/todoModule.js
const state = {
todos: [],
};
const mutations = {
ADD_TODO(state, todo) {
state.todos.push(todo);
},
TOGGLE_TODO(state, todoId) {
const todo = state.todos.find((todo) => todo.id === todoId);
if (todo) {
todo.completed = !todo.completed;
}
},
};
const actions = {
addTodo({ commit }, todo) {
commit('ADD_TODO', todo);
},
toggleTodo({ commit }, todoId) {
commit('TOGGLE_TODO', todoId);
},
};
const getters = {
getTodos: (state) => {
return state.todos;
},
getCompletedTodos: (state) => {
return state.todos.filter((todo) => todo.completed);
},
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
userModule.js:
// store/modules/userModule.js
const state = {
user: null,
};
const mutations = {
SET_USER(state, user) {
state.user = user;
},
};
const actions = {
login({ commit }, user) {
// 로그인 로직 처리
commit('SET_USER', user);
},
logout({ commit }) {
// 로그아웃 로직 처리
commit('SET_USER', null);
},
};
const getters = {
getUser: (state) => {
return state.user;
},
isLoggedIn: (state) => {
return state.user !== null;
},
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};
반응형
'Front-End > Vue.js' 카테고리의 다른 글
Vue.js mixin 사용 방법: 코드 재사용 및 컴포넌트 공유 (0) | 2023.10.16 |
---|---|
Vue.js this.$set 반응성 유지를 위한 방법 (0) | 2023.07.25 |
Vue.js Vue에서 배열(Array) 변경 감지하기 (0) | 2023.07.13 |
Vue.js ref 속성으로 요소와 컴포넌트에 쉽게 접근하기 (0) | 2023.07.12 |
Vue.js computed 속성에 파라미터 전달하기 (0) | 2023.07.10 |