vue

vue.js Event Bus를 통해 컴포넌트간 통신하기 (Event Bus in Vue.js)

vue.js에서는 일반적으로 부모/자식간의 이벤트 통신하는 방식을 사용합니다. 하지만, 경우에 따라서는 서로 관련없는 독립적인 컴포넌트끼리 이벤트를 통신해야할 때가 생깁니다. 이 경우를 좀 더 편하게 도와주는 vuex라는 state 관리 라이브러리도 있지만 규모가 작을 경우에는 단순히 EventBus를 활용해서 간단하게 처리할 수 있습니다.

이벤트버스 초기화

이벤트버스를 구현하는 것은 매우 쉽습니다. 단지 아래와 같이 하나의 vue 인스턴스만 생성해주면 됩니다. 이 인스턴스를 독립적인 각 컴포넌트끼리 통신할 때 중간지로 활용합니다.

vue component -> EventBus -> vue component

// event-bus.js
import Vue from "vue";
export const EventBus = new Vue();

이벤트버스 사용해보기

이벤트버스를 만들었으니 이제 이벤트가 필요한 컴포넌트에서 불러오기만하면 됩니다.

이벤트 발행

<template>
  <section>
    <button @click="handleGlobalClickButton">click</button>
  </section>
</template>

<script>
import { EventBus } from "~/utils/event-bus";
export default {
  data() {
    return {
      clickedCount: 0
    };
  },
  methods: {
    handleGlobalClickButton() {
      this.clickedCount++;

      EventBus.$emit("use-eventbus", this.clickedCount);
    }
  }
};
</script>

핵심은 아래 구문입니다. 클릭이벤트가 발생할 때, EventBus의 $emit메소드를 통해 이벤트를 내보낼 수 있습니다. 첫 번째 파라미터는 이벤트채널 이름, 두 번째 파라미터는 이벤트가 발생했을 때 같이 내보내고싶은 데이터를 설정할 수 있습니다.

EventBus.$emit("use-eventbus", this.clickedCount)
// use-eventbus의 이벤트이름으로 clickedCount 데이터를 포함해서 이벤트를 내보낸다.

이벤트 구독

서로 부모/자식 간의 컴포넌트가 아닌 다른 독립된 컴포넌트에서 좀전의 clickedCount 데이터를 사용하고 싶을 때는 아래와 같이 EventBus를 불러와서 데이터를 받아볼 수 있습니다.

<template>
  <section>
    {{ receivedClickCount }}
  </section>
</template>

<script>
import { EventBus } from "~/utils/event-bus";
export default {
  data() {
    return {
      receivedClickCount: 0
    };
  },
  created() {
    EventBus.$on("use-eventbus", clickedCount => {
      this.receivedClickCount = clickedCount;
    });
  }
};
</script>

핵심은 아래의 코드입니다. 이벤트를 내보낼 때 $emit 메소드에 이벤트이름과 데이터를 포함해서 내보냈던 것 기억하시죠? 이벤트를 받을 때에는 $on메소드를 활용해서 첫 번째 파라미터에 이벤트 이름, 두 번째 파라미터로는 콜백함수를 지정합니다. 콜백함수에서의 파라미터로 이벤트버스를 내보낼 때 지정한 데이터들을 받아볼 수 있습니다.

EventBus.$on("use-eventbus", clickedCount => {
  this.receivedClickCount = clickedCount;
});

이벤트를 한번만 받아보고 싶다면? 아래와 같이 $once 메소드를 사용하면 됩니다.

EventBus.$once("use-eventbus", clickedCount => {
  this.receivedClickCount = clickedCount;
});

이벤트버스 해제

이벤트버스를 해제하는 것도 간단합니다. $off 메소드를 활용하면 이벤트버스 연결을 해제할 수 있습니다.

EventBus.$off("use-eventbus");

만약 해당 이벤트이름을 가진 이벤트버스를 해제하는 것이 아닌 모든 이벤트버스를 해제하고 싶다면, EventBus.$off();를 사용하면 됩니다.