본문 바로가기
Programming/Vue.js

Vue.js에서 mitt을 이용한 멀리있는 컴포넌트간 데이터 전송

by 주리니e 2022. 12. 23.
728x90

Vue.js에서 mitt을 이용한 멀리있는 컴포넌트간 데이터 전송

 

 

Props, Slot, Custom Events는 상위 컴포넌트와 하위 컴포넌트 간의 데이터 통신을 지원한다. 하지만 연결되어 있지 않은 컴포넌트간 데이터 통신 또는 상위의 상위 등 은 지원하지 않는데 이때는 mitt을 이용하면 된다. mitt은 모든 컴포넌트 간 데이터 통신을 지원한다. Vue2에서는 Event Bus라는 것을 이용해 멀리 있는 컴포넌트간 데이터를 전송했지만 Vue3부터는 지원하지 않아 mitt 외부 라이브러리를 따로 사용해야 한다.

 

  • 샘플 프로젝트 생성
> vue create mitt-test



  • 데이터 전송

App.vue는 하위 컴포넌트로 ManView.vue와 WomanView.vue를 가지고 있다. ManView.vue는 WomanView.vue와 형제 컴포넌트로서 직접적인 상관관계가 없다. ManView가 가지고 있는 사탕개수는 10개이며 '사탕 나눠주기' 버튼을 클릭할때마다  WomanView로 1개씩 사탕을 건네준다. 이런식으로 mitt을 통한 데이터 통신을 예제 프로그램을 만들어보자.



  • mitt 설치
> npm install mitt



  • main.js의 mitt 설정

main.js에 mitt을 임포트하여 globalProperties로 emitter를 등록할 수 있다. globalProperties은 모든 컴포넌트에서 사용할 수 있는 변수를 등록할 수 있도록 도와주는 역할을 한다.

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'

let emitter = mitt();
let app = createApp(App);

app.config.globalProperties.emitter = emitter;

app.mount('#app')

 

  • App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <Man />
  <Woman />
</template>

<script>
import Man from "./components/ManView.vue";
import Woman from "./components/WomanView.vue";

export default {
  name: "App",
  components: {
    Man,
    Woman,
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 20px;
}

.area {
  width: 100%;
  height: 150px;
  margin: 20px 50px 50px auto;
  border: 1px solid black;
}
</style>

 

  • ManView.vue

'캔디 나눠주기' 버튼을 클릭하면 fire 함수가 호출되며 가지고 있는 캔디를 1개씩 this.emitter.emit('이벤트명', 데이터) 구문을 이용해 보낸다. 보낸 캔디의 숫자는 하나씩 줄어든다.

<template>
  <div class="area">
    <h3>남자 영역</h3>
    <p>남자 캔디 개수 : {{ candy }}</p>
    <button @click="fire">캔디 나눠주기</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      candy: 10,
    };
  },
  methods: {
    fire() {
      console.log(this.candy);
      if (this.candy >= 1) {
        this.emitter.emit("candy", 1);
        let remain = this.candy - 1;
        this.candy = remain;
      } else {
        alert("나눠줄 캔디가 부족합니다.");
      }
    },
  },
};
</script>

<style></style>

 

 

  • WomanView.vue

보통 수신하는 코드는 mounted()로 받으며 this.emitter.on("이벤트명, (데이터) 구문으로 데이터를 받는다. 받은 캔디 개수를 하나씩 가지고 있는 캔디에 더해준다.

<template>
  <div class="area">
    <h3>여자 영역</h3>
    <p>여자 캔디 개수 : {{ candy }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      candy: 0,
    };
  },
  mounted() {
    this.emitter.on("candy", (a) => {
      this.candy = this.candy + a;
    });
  },
};
</script>

<style></style>

 

 

  • mitt 데이터 송수신 화면

 

  • 기본 mitt 데이터 송·수신 문법
// 데이터 송신
this.emitter.emit('이벤트명', '데이터')
// 데이터 수신
this.emitter.on('이벤트명', (a) => {
  console.log(a);
  실행 코드
})

 

728x90

댓글