|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "vue.js EventBus를 활용한 컴포넌트간 데이터 공유" |
| 4 | +date: 2017-02-13 22:17:00 +0900 |
| 5 | +categories: jekyll update |
| 6 | +author: "developerjin" |
| 7 | +excerpt: "EventBus를 활용하여 Vue 혹은 Component간의 정보를 공유해보는 예제를 살펴봅니다." |
| 8 | +--- |
| 9 | + |
| 10 | +프론트엔드 프레임워크를 사용하다보면 왠지 모르게 빡빡하게 짜여져 제공되는 것들 때문에 데이터의 흐름이나 여러 핸들링을 처리하기에 어려움을 겪기도 합니다. |
| 11 | +제가 현재 작성하고 있는 `Vue.js`의 경우도 이러한 부분 때문에 클래식(?)스타일로 웹개발을 하시는 분들은 부담스러운 부분들도 있습니다. |
| 12 | +데이터의 흐름을 쉽게 하기 위해 `vuex`라는 외부라이브러리가 있고, 메소드들을 서로 호출할 수 있도록 도와주는 `EventBus`라는 방법이 있습니다. 저는 이러한 것들 중에서 `EventBus`라는 것의 대해서 살펴보고 예제를 작성해보려 합니다. |
| 13 | + |
| 14 | +## 이벤트를 사용하는 이유 |
| 15 | +일반적으로 메소드, 변수를 정의할 때 한 오브젝트나 컴포넌트 단위로 묶어서 사용되기 때문에 이벤트를 사용할 필요가 없이 현재위치에 포함된 메소드/변수를 호출하여 사용할 수 있습니다. 하지만 각각 분리되어 있는 개체에 전송하거나 알려줘야한다면 어떻게 해야할까요? 이럴때 공통으로 데이터들을 주고 받을 수 있는 공간을 만들고, 이를 통해서 서로 규격에 맞춰 데이터들을 주고 받으면 될 것 입니다. 과거 스마트폰이라는 개념이 나오기 전까지는 `푸시`라는 것이 생소하고 잘 사용하지도 않았으며, 이보다는 정기적으로 데이터를 긁어오는 `폴링`이라는 것이 더 사용했던 것 같습니다. 하지만 최근에는 `푸시`라는 용어와 함께 토픽, 구독, 발행등의 단어들을 사용하고 있는데 제 개인적으로는 이러한 것들이 이벤트와 비슷한 개념으로 받아들여도 되지 않을까라고 조심스럽게 의견을 내봅니다. |
| 16 | +이벤트를 등록하고 받을 준비가 끝났다면 언제 어디서든지 데이터들을 주고 받고, 각 이벤트요청 상황에 따라 원하는 메소드들을 수행할 수 있을 것입니다. |
| 17 | + |
| 18 | +## vue.js의 EventBus |
| 19 | + |
| 20 | +vue.js에서 이벤트를 쉽게 다루기 위해 EventBus라는 개념을 이용할 수 있으며, 누구나 쉽게 사용할 수 있습니다. |
| 21 | +```javascript |
| 22 | +// 이벤트버스 생성 |
| 23 | +var EventBus = new Vue() |
| 24 | +``` |
| 25 | + |
| 26 | +```javascript |
| 27 | +// 이벤트 발행 |
| 28 | +EventBus.$emit('message', 'hello world'); |
| 29 | +``` |
| 30 | + |
| 31 | +```javascript |
| 32 | +// 이벤트 구독 |
| 33 | +EventBus.$on('message', function(text) { |
| 34 | + console.log(text); |
| 35 | +}); |
| 36 | +``` |
| 37 | + |
| 38 | +자, 이렇게 하여 vue.js에서 이벤트를 쉽게 활용할 수 있습니다. 위와 같이 구현해놓는다면 컴포넌트가 전혀 다르더라도 서로 쉽게 호출할 수 있습니다. |
| 39 | + |
| 40 | +## 컴포넌트간 이벤트 주고받기 |
| 41 | + |
| 42 | +컴포넌트보다 한단계 위의 단계인 `VueApp`간의 이벤트 공유로 예제를 드리도록 하겠습니다. (제가 EventBus를 보면서 컴포넌트끼리 데이터주고 받는 것보다 극단적인 상황인 App단계에서의 이벤트공유가 가능여부가 더 궁금했었고, 이 글을 읽고 계신분들도 이 예제가 더 도움이 많이 될 것 같아 이렇게 진행했습니다.) |
| 43 | + |
| 44 | +```xml |
| 45 | +<div id="sender-app"> |
| 46 | + <input v-model="text"> |
| 47 | + <button @click="sender">sender</button> |
| 48 | + <div v-if="receiveText">#sender-app: I sent a message a {{ receiveText }}</div> |
| 49 | +</div> |
| 50 | +<div id="receiver-app"> |
| 51 | + <div v-if="text">#receiver-app: {{ text }}</div> |
| 52 | +</div> |
| 53 | +``` |
| 54 | + |
| 55 | +```javascript |
| 56 | +var EventBus = new Vue(); |
| 57 | + |
| 58 | +var SenderApp = new Vue({ |
| 59 | + el: '#sender-app', |
| 60 | + data() { |
| 61 | + return { |
| 62 | + text: '', |
| 63 | + receiveText: '' |
| 64 | + } |
| 65 | + }, |
| 66 | + created() { |
| 67 | + EventBus.$on('message', this.onReceive); |
| 68 | + }, |
| 69 | + methods: { |
| 70 | + sender() { |
| 71 | + EventBus.$emit('message', this.text); |
| 72 | + this.text = ''; |
| 73 | + }, |
| 74 | + onReceive(text) { |
| 75 | + this.receiveText = text; |
| 76 | + } |
| 77 | + } |
| 78 | +}); |
| 79 | + |
| 80 | +var ReceiverApp = new Vue({ |
| 81 | + el: '#receiver-app', |
| 82 | + data() { |
| 83 | + return { |
| 84 | + text: '' |
| 85 | + } |
| 86 | + }, |
| 87 | + created() { |
| 88 | + EventBus.$on('message', this.onReceive); |
| 89 | + }, |
| 90 | + methods: { |
| 91 | + onReceive(text) { |
| 92 | + this.text = text; |
| 93 | + } |
| 94 | + } |
| 95 | +}); |
| 96 | +``` |
| 97 | + |
| 98 | +위 예제에서 확인했듯이 `SenderApp`과 `ReceiverApp`이 서로 다른 `VueApp`임에도 불구하고 `EventBus`를 통해 이벤트를 공유할 수 있습니다. |
| 99 | + |
| 100 | +만약에 EventBus를 공용으로 사용하는 것이 아닌 Vue내에서만 사용하고 싶으시다면 아래와 같이 Vue내장함수로 사용할 수 있습니다. |
| 101 | + |
| 102 | +```javascript |
| 103 | +(function() { |
| 104 | + |
| 105 | + var EventBus = Vue(); |
| 106 | + |
| 107 | + Object.defineProperties(Vue.prototype, { |
| 108 | + $eventBus: { |
| 109 | + get: function () { |
| 110 | + return EventBus; |
| 111 | + } |
| 112 | + } |
| 113 | + } |
| 114 | +})(); |
| 115 | +``` |
| 116 | +
|
| 117 | +관련 예제는 [Github](https://github.com/devjin0617/vuejs-eventbus-example)을 통해 공유되어 있으며, 궁금한 내용있으시면 [Github Issue](https://github.com/devjin0617/vuejs-eventbus-example/issues)를 통해 언제든지 알려주시면 감사하겠습니다. |
| 118 | +
|
| 119 | +## 참고자료 |
| 120 | +
|
| 121 | +- [vue.js 공식홈페이지 - 비-부모-자식간-통신](https://kr.vuejs.org/v2/guide/components.html#비-부모-자식간-통신) |
| 122 | +- [Building a Simple Event Bus in Vue.js - Arvid Kahl](https://devblog.digimondo.io/building-a-simple-eventbus-in-vue-js-64b70fb90834#.ksf302nhz) |
| 123 | +- [vue.js 한국어 사용자 모임](https://vuejs-kr.github.io/) |
| 124 | +- [진블로그 - Vuejs EventBus](http://blog.puding.kr/179) |
0 commit comments