본문 바로가기
Vue

Vue - Vuex

by sinabeuro 2022. 3. 25.
728x90

 

Vuex란?

Vuex는 Vue.js 애플리케이션에 대한 상태 관리 패턴 + 라이브러리 입니다. 애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있습니다.

 

즉, Vuex를 통해서 어플리케이션 전체에서 사용할 수 있는 전역 변수들을 선언하고 관리, 호출, 재사용 등을 가능하게 합니다. 

Vuex는 컴포넌트에서 공유된 상태를 추출하고 이를 전역 싱글톤으로 관리합니다.

이를 통해 Vuex의 컴포넌트 트리는 커다란 Vue가 되며 모든 컴포넌트는 트리에 상관없이 상태에 액세스하거나 동작을 트리거 할 수 있습니다.

 

 

Vuex 설치 

npm i vuex

 

 


 

Vuex state

Vuex 기본 틀은 다음과 같습니다.

import Vue from 'vue';
import Vuex from 'vuex';
import { saveAuthToCookie, saveUserToCookie, getAuthFromCookie, getUserFromCookie } from '@/utils/cookies';

Vue.use(Vuex);

export default new Vuex.Store({
	// state란 여러 컴포넌트에서 공유되는 데이터를 말한다.
	state: {
		username: getUserFromCookie() || '',
		token: getAuthFromCookie() || '',
	},
	getters: {
		isLogin(state) {
			return state.username !== '';
		},
	},
	...
});

state 속성에 어플리케이션 내에 있는 모든 컴포넌트에서 공유되는 데이터를 정의합니다.

예시에서 볼 수 있듯이 username, token를 정의하고 초기값을 부여합니다. 

초기값은 다른 메소드에서 리턴하는 값으로도 세팅할 수 있으며, 딱히 초기값이 필요없으면 ''이나 null로 주셔도 상관없습니다.

 

html에서는 $store.state.username

vue 컴포넌트에서는 this.$store.state.username 와 같은 문법을 통해서 vuex에 저장된 state 값을 호출할 수 있습니다. 

 

this.$store.state.username로 접근해서 값을 수정할 수 있지만, 이 방법은 그다지 추천드리지 않습니다.

아래에 언급할 mutations을 통해서 vuex의 state가 수정하는 것을 권장합니다. (싱글톤 인스턴스 참조)

 

 

getters

vuex state에 접근할 수 있는 메소드가 있습니다. 

getters 속성을 활용해서 접근할 state 값을 리턴하는 메소드를 작성하면 됩니다.

다만, state 값을 그대로 리턴하는 것보다 state 값을 통해서 조건이나 상태를 확인하는 용도로 메소드를 만드시면 좋을 것 같습니다.

 

vue 컴포넌트 내부에서는 다음과 같이 getters를 호출하면 됩니다.

this.$store.getters.isLogin

 

js 내부에서는 import를 사용해서 호출해야합니다. 

import store from '../store/index';

const isLogin = store.getters.isLogin;

 


 

Mutations

import Vue from 'vue';
import Vuex from 'vuex';
import { saveAuthToCookie, saveUserToCookie, getAuthFromCookie, getUserFromCookie } from '@/utils/cookies';

Vue.use(Vuex);

export default new Vuex.Store({
	// state란 여러 컴포넌트에서 공유되는 데이터를 말한다.
	state: {
		username: getUserFromCookie() || '',
		token: getAuthFromCookie() || '',
	},
	getters: {
		...
	},
	// state를 바꾸는 것이 mutations 이다.
	mutations: {
		setUsername(state, username) {
			state.username = username;
		},
		clearUsername(state) {
			state.username = '';
		},
		setToken(state, token) {
			state.token = token;
		},
		clearToken(state) {
			state.token = '';
		},
	},
});

mutation은 state 값을 변경시키는 핸들러 함수입니다.  

mutation은 직접적으로 호출할 수 없으며,  store.commit 이라는 메소드에 의해 호출될 수 있습니다.

호출된 mutation 내부에서 state 값의 수정이 이루어집니다.

 

vue 컨포넌트 내에서 다음과 같이 mutation을 호출할 수 있습니다.

this.$store.commit('setToken', data.token);
this.$store.commit('setUsername', data.user.username);


// 객체 스타일 커밋
this.$store.commit({
	type: 'setToken', 
    token: data.token
});
this.$store.commit({
	type: 'setUsername', 
    username: data.user.username
});

 

js 내에서는 import를 이용해서 mutation을 호출할 수 있습니다.

import store from '../store/index';

store.commit('setToken', data.token);
store.commit('setUsername', data.user.username);

 

Vue의 반응성 규칙을 따르는 mutation

Vuex 저장소의 상태는 Vue에 의해 반응하므로, state를 변경하면 state를 관찰하는 Vue 컴포넌트가 자동으로 업데이트됩니다. 

이 때문에 경우에 따라서 vuex store의 state를 초기화하거나,

객체에 새 속성을 추가할 때 다음 중 하나를 수행해야합니다.

Vue.set(obj, 'newProp', 123)을 사용하거나, state.obj = { ...state.obj, newProp: 123 } 와 같이 객체를 새로운 것으로 교체해야합니다.

 

 


 

Actions

action은 mutation과 유사하게 state의 값을 변경하기 위해 사용합니다.

다만 차이점은 mutation은 state를 변경시키는 핸들러이지만, action은 mutation을 변경시키는 핸들러입니다.

즉, action을 호출하면 mutation을 commit으로 호출하여 state를 변경하게 합니다.

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

action 핸들러는 저장소 인스턴스의 같은 메소드들/프로퍼티 세트를 드러내는 컨텍스트 객체를 받습니다.

그래서 context.commit을 호출하여 mutation을 커밋하거나 context.state context.getters를 통해 상태와 getters에 접근 할 수 있습니다.

 

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

action 핸들러 ES6 문법인 구조분해 할당을 통해 간략하게 표현할 수 있습니다.

 

// vue 컴포넌트 내부에서 호출
this.$store.dispatch('increment')

// js에서 호출
store.dispatch('increment')

action 메소드는 dispatch를 통해서 호출할 수 있습니다.

 

 


 

vuex 참고 예시

import Vue from 'vue';
import Vuex from 'vuex';
import {
	saveAuthToCookie,
	saveUserToCookie,
	getAuthFromCookie,
	getUserFromCookie,
} from '@/utils/cookies';
import { loginUser } from '@/api/auth';

Vue.use(Vuex);

export default new Vuex.Store({
	// state 란 여러 컨포넌트에서 공유되는 데이터를 말한다.
	state: {
		username: getUserFromCookie() || '',
		token: getAuthFromCookie() || '',
	},
	getters: {
		isLogin(state) {
			return state.username !== '';
		},
	},
	// state를 바꾸는 것이 mutations 이다.
	mutations: {
		setUsername(state, username) {
			state.username = username;
		},
		clearUsername(state) {
			state.username = '';
		},
		setToken(state, token) {
			state.token = token;
		},
		clearToken(state) {
			state.token = '';
		},
	},
	actions: {
		async LOGIN({ commit }, userData) {
			const { data } = await loginUser(userData);
			commit('setToken', data.token);
			commit('setUsername', data.user.username);
			return data; // 굳이 return을 하지 않아도 프로미스가 반환된다.
		},
	},
});

 

await this.$store.dispatch('LOGIN', userData);

dispatch 메소드로 action을 호출합니다.

 

 

 

 

 

 

https://vuex.vuejs.org/kr/

 

Vuex가 무엇인가요? | Vuex

Vuex가 무엇인가요? Vuex는 Vue.js 애플리케이션에 대한 상태 관리 패턴 + 라이브러리 입니다. 애플리케이션의 모든 컴포넌트에 대한 중앙 집중식 저장소 역할을 하며 예측 가능한 방식으로 상태를

vuex.vuejs.org

 

728x90

'Vue' 카테고리의 다른 글

Vue - axios Interceptors  (0) 2022.03.25
Vue - axios (Http 통신)  (0) 2022.03.25
Vue에서 fontawesome 설치 및 적용  (0) 2022.02.16
Vue - 팝업 창에서 뒤로가기 구현  (0) 2022.02.07
Vue 컴퍼넌트(Component) - 페이징 처리  (0) 2021.06.10

댓글