ksundev 님의 블로그

Vue의 Component 통신 방식 - 3. 같은 level 끼리 본문

[개발] Vue.js/기본

Vue의 Component 통신 방식 - 3. 같은 level 끼리

ksundev 2025. 6. 21. 16:18

Vue.js에서 같은 레벨 컴포넌트 간 통신 방식

Vue.js에서 컴포넌트 간 통신은 프론트엔드 개발에서 매우 중요한 개념입니다. 특히 같은 레벨(sibling components)에 있는 컴포넌트들 간의 통신은 자주 사용되는 패턴입니다. 이번 포스트에서는 Vue.js에서 같은 레벨 컴포넌트 간 통신을 구현하는 방법을 살펴보겠습니다.

부모 컴포넌트를 통한 통신 (Event Bus 패턴)

가장 일반적이고 권장되는 방법은 부모 컴포넌트를 중간자(mediator)로 사용하는 것입니다. 이 방법은 Vue.js의 단방향 데이터 플로우 원칙을 따르며, 데이터의 흐름을 예측 가능하게 만듭니다.

기본 구조

부모 컴포넌트
├── 자식 컴포넌트 A (이벤트 발생)
└── 자식 컴포넌트 B (이벤트 수신)

구현 예제

<!-- HTML -->
<div id="app">
  <app-header v-bind:app-title="message"></app-header>
  <app-contents v-on:login="receive"></app-contents>
</div>

<!-- JavaScript -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  var appHeader = {
    template: `<h1>{{ appTitle }}</h1>`,
    props: ["appTitle"],
  };

  var appContents = {
    template: `<button v-on:click="sendEvent">로그인</button>`,
    methods: {
      sendEvent() {
        this.$emit("login");
      },
    },
  };

  // 루트컴포넌트
  Vue.createApp({
    data() {
      return {
        message: "로그인 하세요",
      };
    },
    components: {
      "app-header": appHeader,
      "app-contents": appContents,
    },
    methods: {
      receive() {
        console.log("받았다");
        this.message = "로그인 되었습니다";
      },
    },
  }).mount("#app");
</script>

동작 원리

  1. 이벤트 발생: app-contents 컴포넌트에서 버튼 클릭 시 this.$emit("login")을 통해 이벤트를 발생시킵니다.
  2. 부모 컴포넌트에서 이벤트 수신: 부모 컴포넌트에서 v-on:login="receive"를 통해 이벤트를 수신합니다.
  3. 데이터 업데이트: 부모 컴포넌트의 receive 메서드가 실행되어 message 데이터를 업데이트합니다.
  4. Props를 통한 데이터 전달: 업데이트된 messageapp-header 컴포넌트의 appTitle prop으로 전달됩니다.

Props와 이벤트의 조합

Vue.js에서 컴포넌트 간 통신의 기본 원칙은 다음과 같습니다:

  • Props Down: 부모에서 자식으로 데이터 전달
  • Events Up: 자식에서 부모로 이벤트 전달

위 예제에서 app-contents 컴포넌트는 로그인 버튼을 클릭하면 login 이벤트를 부모 컴포넌트로 전달하고, 부모 컴포넌트는 이 이벤트를 받아서 message 데이터를 업데이트합니다. 그리고 업데이트된 messageapp-header 컴포넌트의 appTitle prop으로 전달되어 화면에 표시됩니다.

장점과 단점

장점

  1. 예측 가능한 데이터 플로우: 단방향 데이터 플로우로 인해 데이터의 흐름을 쉽게 추적할 수 있습니다.
  2. 디버깅 용이성: 이벤트와 props를 통해 데이터가 어떻게 전달되는지 명확하게 알 수 있습니다.
  3. Vue.js 철학 준수: Vue.js의 공식 권장사항을 따르는 방식입니다.
  4. 컴포넌트 재사용성: 각 컴포넌트가 독립적으로 동작하여 재사용이 용이합니다.

단점

  1. Props Drilling: 깊은 컴포넌트 계층에서 props를 여러 단계 거쳐 전달해야 할 수 있습니다.
  2. 복잡성 증가: 컴포넌트가 많아질수록 부모 컴포넌트가 복잡해질 수 있습니다.

대안적 방법들

Vuex (상태 관리 라이브러리)

복잡한 애플리케이션에서는 Vuex를 사용하여 전역 상태를 관리할 수 있습니다.

Provide/Inject

Vue 2.2+ 에서 제공하는 기능으로, props drilling 문제를 해결할 수 있습니다.

Event Bus (Vue 2)

Vue 2에서는 전역 이벤트 버스를 사용할 수 있었지만, Vue 3에서는 제거되었습니다.

실무 적용 팁

  1. 명확한 이벤트 이름 사용: login 등 명확하고 의미있는 이벤트 이름을 사용하세요.
  2. Props 검증: 복잡한 데이터를 전달할 때는 props 검증을 추가하세요.
  3. 컴포넌트 분리: 하나의 컴포넌트가 너무 많은 책임을 가지지 않도록 적절히 분리하세요.
  4. 문서화: 컴포넌트 간 통신 방식에 대한 문서를 작성하여 유지보수성을 높이세요.

결론

Vue.js에서 같은 레벨 컴포넌트 간 통신은 부모 컴포넌트를 중간자로 사용하는 것이 가장 권장되는 방법입니다. 이 방식은 Vue.js의 단방향 데이터 플로우 원칙을 따르며, 예측 가능하고 유지보수하기 쉬운 코드를 작성할 수 있게 해줍니다.

작은 규모의 애플리케이션에서는 이 방법이 충분하지만, 애플리케이션이 복잡해지면 Vuex나 다른 상태 관리 라이브러리를 고려해보는 것이 좋습니다.