-
Vuex - stateJavaScript/Vue.js 2019. 3. 11. 13:57
Vuex
Vue.js를 통해 회원가입, 로그인 기능을 포함하는 게시판 프로그램을 하나 만드려고 했는데 한가지 문제에 봉착했다.
그건 바로 로그인 상태에 대하여 모든 컴포넌트 간 상태 데이터를 공유하는 부분이었다.
사용자가 로그인을 했다면 로그인을 한 플래그를 컴포넌트간 공유를 해야 로그인 상태를 유지할 수 있는데,
props나 eventBus를 활용하여 매번 데이터를 상위 컴포넌트 -> 하위 컴포넌트, 하위 컴포넌트 -> 상위 컴포넌트로 전달하기가 버거움이 느껴졌다.
그래서 Vuex에 대하여 알아보고 공부해보려고 한다.
Vuex란
Vue.js의 상태관리를 위한 패턴 라이브러리이다.
Vue의 Reactivity(반응성) 체계를 효율적으로 활용하여 화면 업데이트가 가능하다.
상태관리가 필요한 이유는 무엇인가
컴포넌트 기반 프레임워크에서는 화면 구성을 매우 작은 단위로 분리하여 구성하게된다.
컴포넌트 간 통신이나 데이터 전달을 좀 더 유기적으로 관리할 필요성이 생긴다.
header → button, button → list, button → footer 등 컴포넌트 간 데이터 전달 및 이벤트 통신의 여러 컴포넌트의 관계를 한 곳에서 관리하기 쉽게 구조화하는 것이 State Management다.
상태관리로 무엇을 할 수 있는가
Vue.js 프레임워크로 컴포넌트 단위 개발을 하게 되면 아래와 같은 문제들이 발생한다.
1. Vue의 기본 컴포넌트 통신 방식인 상위 - 하위 컴포넌트에서 중간에 거쳐야 할 컴포넌트가 많아지거나
2. 이를 피하기 위해 EventBus를 활용하여 상하위 관계가 아닌 컴포넌트 간 통신시 관리가 되지 않는 점
이러한 문제점들을 해결하기 위해 모든 데이터 통신을 한 곳에서 중앙 집중식으로 관리한다.
(Vue와 Backend, Devtools간 작업 흐름도에서 Vuex가 관리하는 범위 관계도이다.)
상태관리 패턴
상태관리 구성요소는 크게 3가지가 있다.
- state : 컴포넌트 간 공유될 data를 관리하는 속성
- view : 데이터가 표현될 template 속성
- actions : 사용자의 입력에 따라 반응할 methods 속성
123456789101112131415161718new Vue({// statedata () {return {count: 0}},// viewtemplate: `<div>{{ count }}</div>`,// actionsmethods: {increment () {this.count++}}})cs 위의 구성 요소의 작업 흐름은 아래와 같다.
Props로 통신하는 Vue App 구성
Vuex의 필요성을 느낄 수 있도록 Props 속성을 통해 상-하위 컴포넌트간 통신하는 간단한 애플리케이션을 만들어보자.
1. +와 -버튼을 클릭하면 counter 데이터의 값이 증가하거나 감소한다.
2. 변경된 값을 상위 컴포넌트와 하위 컴포넌트가 서로 공유한다.
3. 상위 - 하위 컴포넌트 간 데이터 전달을 위해 props를 사용한다.
아래와 같은 컴포넌트 구조를 만들자.
- App.vue : 상위 컴포넌트 역할을 담당한다.
- Child.vue : 하위 컴포넌트 역할을 담당한다.
App.vue 코드를 보자.data 속성을 선언했고, data 속성을 증가 및 감소 시키는 이벤트를 등록했다.
Child.vue 코드를 보자.
App.vue에서 전달받은 counter 데이터를 props로 등록했다.
위의 애플리케이션을 실행하고 사용해보면 아래와 같이 작동하는 것을 알 수 있다.
+버튼을 클릭하면 숫자가 증가하는데 상위 컴포넌트와 하위 컴포넌트 모두 값이 증가하여 표현된다.
-버튼을 클릭하면 숫자가 감소하고 상위 컴포넌트와 하위 컴포넌트 모두 값이 감소하여 표현된다.
이러한 이유는 상위 컴포넌트의 counter 데이터를 하위 컴포넌트에서 props로 넘겨받았기 때문이다.
동일한 데이터 속성을 2개의 컴포넌트에서 동시에 참조하여 같은 값을 표현하고 있다.
이러한 컴포넌트간 통신 방법은 데이터가 많아질 수록, 컴포넌트가 많아질 수록 관리가 힘들어지게 된다.
이러한 비효율적인 컴포넌트간 통신 관리를 Vuex로 해결해보자.
Vuex 설치 및 사용방법
Vuex를 사용하기 위해 npm으로 패키지를 설치하도록 하자.
src 하위에 store.js라는 이름으로 스크립트 파일을 하나 생성한다.
store.js를 열고 Vuex 객체를 생성하자.
(Vuex와 같은 확장 라이브러리를 사용하려면 반드시 Vue객체에 use함수를 이용하여 사용 등록해야한다.)
그리고 VueApp이 등록된 main.js에 store.js를 불러오고 인스턴스에 불러온 Vuex 객체를 등록해준다.
state 속성 등록
state 속성을 Vuex에 아래와 같이 등록할 수 있다.
state는 컴포넌트 간에 공유할 data 속성을 의미한다.
state에 정의된 counter 속성은 상위 컴포넌트(App.vue)에서 사용하던 data 속성 counter이다.
state 속성 접근
state에 등록한 counter를 앱에서 접근하려면 전역으로 등록된 $store 속성으로 접근할 수 있다.
App.vue를 Vuex에 정의한 데이터를 사용하여 작동하도록 수정하자.
콧수염 괄호 표현식에서 this.$store.state.counter로 속성에 접근했다.
여기서 this는 인스턴스 객체를 가리키므로 의미를 정리하자면 다음과 같다.
this : 뷰 인스턴스 객체에서
$store : 전역으로 등록한 Vuex store 객체에 접근하여
state : 정의한 state 속성에서
counter : counter 값을 가져온다.
그리고 기존 v-bind 디렉티브를 이용하여 props로 데이터를 전달했던 태그를 지우고 <child>커스텀 태그를 하나 만든다.
그리고 스크립트를 수정하자.
기존 props로 통신하기 위해 정의했던 data()를 더 이상 사용하지 않으므로 지우자.
그리고 data()에서 정의한 counter 속성을 증감처리 했던 부분을 Vuex의 store에 정의한 counter 속성을 증감처리하도록 코드를 변경하자.
결과적으로 상위 컴포넌트(App.vue)에서 관리했던 counter 데이터를 Vuex에 state로 넘겨준 것이다.
이제 상위 컴포넌트와 하위 컴포넌트 모두 Vuex의 state를 바라보게 되었다.
이제 Vuex라는 저장소의 데이터를 모든 컴포넌트들이 동일한 조건에서 접근하여 사용하게 된다.
Child.vue도 수정해보자.
props로 받아와서 화면에 출력했던 방식에서 뷰 인스턴스의 store 속성에 접근해서 데이터를 가져오도록 변경했다.
스크립트도 수정하자.
props로 데이터를 받아온다고 정의한 props 속성을 지우자.
애플리케이션을 실행시키고 직접 조작해보면 props로 처리했던 방식과 동일하게 작동하는 것을 알 수 있다.
결론
Vuex의 state를 이용하여 데이터 관리를 한 곳에서 효율적으로 할 수 있다는 것이 증명되었다.
참고 :
https://joshua1988.github.io/web-development/vuejs/vuex-start/
'JavaScript > Vue.js' 카테고리의 다른 글
Vuex - Mutations (0) 2019.03.11 Vuex - Getters (0) 2019.03.11 [vue-router] SPA 방식 애플리케이션 운영 시 주의사항 (4) 2019.03.09 Spring Boot와 Vue.js 연동하기 (9) 2019.03.03 뷰 프로젝트 구성 방법 (0) 2019.03.01