[Vue.JS] Vuex VS Event Bus
Vue에서 컴포넌트 간 통신은 props
와 emit
을 통해서 주고받는다.
보통 이런 관계는 상위 컴포넌트인 부모 컴포넌와 하위 컴포넌트인 자식 컴포넌트에서 가지는데 자식 컴포넌트의 깊이에 따라 props
와 emit
이 많아지므로 관리에 어려움이 있거나 부모-자식 관계가 아닌 전혀 다른 컴포넌트에게 파라미터 또는 값을 전달할 수가 없다는 문제점이 있다. 이런 문제점을 해결하기 위해서는 흔히 우리는 두 가지 방법을 사용한다.
첫 번째는 가장 많이 사용되는 상태 관리 패턴 라이브러리인 Vuex이다.Vuex
는 Flux의 아키텍처를 따라가고 있으며, 중앙 집중식 저장소 역할을 한다. Vuex
에 대해서는 [Vue.JS] Vuex 개념부터 실무에서의 사용까지 배우기!!를 참고하자.
두 번째 방법은 Event Bus이다.Event Bus
는 특정 라이브러리나 특정 개념 또는 모듈 이름이 아닌 Vue 객체 그대로이다. Vue 객체 인스턴스를 통하여 $on
, $off
, $emit
API를 사용하여 N 개의 이벤트를 등록, 호출 할 수 있는 형태이기 때문에 Bus라는 단어가 붙는다. vue에서는 이를 Global Event Bus
또는 Global Event Hub
이라고 부른다.
두 방식의 공통점은 별도의 위치에서 상태를 관리하므로 비 부모-자식 간 컴포넌트 통신이 가능하다. Vuex의 경우는 중앙 집중식 상태 관리 패턴이므로 어느 컴포넌트에서나 접근이 가능하고, Event Bus의 경우 Global Event로 등록되기 때문에 역시 어느 컴포넌트에서도 접근이 가능하다.
그럼 이 두 방식 중 어떤 것을 사용해야 할까?
이 질문에 대한 내용을 이번 포스트에 작성해보고자 한다.
Vuex VS Event Bus
결론부터 말하자면 무조건 Vuex를 사용하자. 이다.
보통 Vuex와 Event Bus와 관련된 글을 보게 되면 이런 글이 많다.
애플리케이션의 크기가 크면 Vuex를 사용하고 규모가 작으면 Event Bus를 사용하는 것이 좋다.
- - -다른 블로그의 글과 개념이 틀렸다는 것이 아니다. 위의 문구 역시 맞는 말이다. 애플리케이션의 규모가 클수록 Event Bus를 사용하기엔 무리가 있다. 그럼에도 불구하고 앱의 규모가 작더라도 무조건 Vuex를 사용하자. 이제 무조건 Vuex를 사용해야 하는 몇 가지 이유를 보자.
Vuex 설정의 번거로움
과거 Vue-CLI가 활성화되기 전에는 Vue 프로젝트를 생성할 때 Vuex 모듈 설치부터 파일 생성까지 하나하나 해줘야 했다. 이러다 보니 규모가 작은 애플리케이션의 경우에는 Vuex 설정보다 더 간편한 Event Bus를 추천하고는 했다. 하지만 현재에서는 Vue-CLI를 사용하면 Vuex의 구조를 잡아준다.
Vue-CLI를 통해서 vue 프로젝트를 scaffolding 할 때 이런 과정에서 Vuex 항목만 선택하면 자동으로 설치해 주는데 앱의 규모가 작더라도 Event Bus를 사용하겠는가?
상태 추적
가장 중요한 부분이다.
Vuex와 Event Bus는 컴포넌트와는 별개로 전혀 다른 위치인 전역 형태로 생성된다. 그러므로 모든 컴포넌트가 접근할 수 있고 모든 컴포넌트가 수정할 수 있으며, 모든 컴포넌트가 삭제할 수도 있다. 하지만 Vuex와 Event Bus의 차이점이라면 상태 추적이다.
Vue를 다루는 개발자라면 vue-devtools를 사용한다. 개발자 도구를 통해서 부모-자식 간의 컴포넌트를 파악하고 Vuex store의 저장 상태를 조회하고 변경 이력을 추적한다. 이 도구를 이용하면 어느 컴포넌트에서 Vuex를 사용하든 어느 정도의 추적이 가능하지만, Event Bus는 알 수가 없다. Event Bus는 상태 관리가 아닌 말 그대로 event
에 필요한 정보를 담고 있기 때문에 패턴을 추적할 순 없다. 추적이 가능하다면 아마도 그건 vue-devtools에서 Events
탭 항목일 것이지만 모든 $emit
이벤트를 기록하기 때문에 사실상 값의 변화를 추적하기는 어렵다.
이렇게 상태를 추적하기 힘든 이유로 인해 애플리케이션의 규모가 작을 경우에 Event Bus를 사용하라는 것이다. 애플리케이션의 규모가 클수록 Event Bus로는 변이를 관찰하기 어렵기 때문이다.
Vue Documents
이전에 Vue 공식 사이트에는 부모-자식 컴포넌트 간의 통신 방법의 하나로서 Event Bus를 기록하고 있었다. 하지만 현재 영문으로 되어 있는 문서에서는 Event Bus에 대한 기록이 없다.
Vue 도큐먼트는 한글로 번역된 자료가 있는데 이 자료에는 비 부모-자식간 통신 항목으로 내용이 기록되어있는 것을 확인 할 수 있다. 하지만 이 자료 역시 위에서 말한 과거 이전의 내용이다.
유추해보자면 이전에는 비 부모-자식 컴포넌트 간의 통신으로 Event Bus를 설명하고 있지만, 시간이 지나감에 따라 해당 내용을 뺐기 때문에 굳이 추천하는 방법은 아니라는 것을 생각해 볼 수 있다.
Vue Style Guide
Vue Style Guide를 보게되면 이곳에도 Event Bus에 대한 언급이 있다.
Non-flux state management를 보게 되면 비 플럭스 상태 관리의 우선순위 규칙은 D로 주의해서 사용해야한다는 내용이다.
Global Event Bus가 대부분의 애플리케이션에 적합하지 않다고 경고하고 있으며, 상태 관리는 Vuex를 사용하기를 유도하고 있다.
Vuex 대신 Event Bus를 사용한다고 하더라도 애플리케이션에 큰 변화를 가져오는 것은 아니다. 하지만 항상 애플리케이션을 개발할 때 고도화와 유지 관리를 생각해야 한다. 시작은 작은 규모의 애플리케이션 일지라도 마지막은 규모가 큰 애플리케이션이 될 수도 있다. 그때서야 Event Bus를 Vuex로 포팅하기엔 이미 $emit
, $on
, $off
의 Hell이 되어있을 것이다. 이런 걸 고려하더라도 Vuex를 사용하는 것이 좋을 것이다.