SPA Framework/Vue

Vue3에서 데이터를 전역으로 전달하는법(mitt)

범데이 2022. 1. 23. 21:42
[운영환경]
vue: 3.0.0
language: typescript

 

 

기존에 Vue2를 사용할때는 전역으로 데이터를 전달하기 위해 EventBus를 사용하였었는데,

EventBus는 이제 Vue에서 추천하는 공식적인 방법이 아니라고 한다.

 

그래서 이 포스팅에서는 'mitt' 라는 외부 라이브러리를 이용하여 이벤트 버스를 구현하고자 한다.

(공식 usage 가이드는 다음 페이지에서 확인할수 있다: https://www.npmjs.com/package/mitt#usage)

 


1. 설치

npm install --save mitt

 

2. 사용

 

2.1 mitt 글로벌 변수 선언

/src 폴더의 main.ts에서 다음과 같이 import하고, globalProperties로 등록해 준다.

import { createApp } from "vue";
import App from "./App.vue";
import mitt from "mitt";

const emitter = mitt();

const app = createApp(App);
app.config.globalProperties.emitter = emitter;

app.mount("#app");

 

2.2 컴포넌트 내 선언

사용하고자 하는 컴포넌트에서 다음과 같이 emitter 변수를 선언해 준다.

<script lang="ts">
import { defineComponent, getCurrentInstance } from "vue";

let emitter: any;

export default defineComponent({
  name: "App",
  created(){
    emitter = getCurrentInstance()?.appContext.config.globalProperties.emitter
  },
  ...
});
</script>

 

 

2.3 데이터 전송

[사용법]

// fire an event
emitter.emit('foo', { a: 'b' })

param1: 이벤트를 전달하고자 하는 key값을 넣는다. (받는곳에서는 해당 key값으로 데이터를 받을 수 있다.)

param2: 전달하고자 하는 데이터를 넣는다.(string, number, object...) 

 

 

(예시)

<script lang="ts">
import { defineComponent, getCurrentInstance } from "vue";

let emitter: any;

export default defineComponent({
  name: "App",
  created(){
    emitter = getCurrentInstance()?.appContext.config.globalProperties.emitter
  },
  methods: {
  	emitData(){
    	const data = "Hello! take the data" // 보내고자 하는 데이터
    	emitter.emit("emitter_test", data)  // 데이터 emit
    }
  }
  ...

 

 

 

 

 

 

 

2.4 데이터 수신

[사용법]

// listen to an event
emitter.on('foo', e => console.log('foo', e) )

param1: 수신하고자 하는 이벤트 key값을 넣는다.

param2: 수신한 데이터로 어떤 것을 할지 작성한다.

 

(예시)

<script lang="ts">
import { defineComponent, getCurrentInstance } from "vue";

let emitter: any;

export default defineComponent({
  name: "App",
  created(){
    emitter = getCurrentInstance()?.appContext.config.globalProperties.emitter
  },
  mounted(){
    emitter.on("emitter_test", (data: any) => console.log(data))  // Hello! take the data
  }
  ...

 

on은 대게 컴포넌트의 mounted() 내에서 사용하여,
컴포넌트가 마운트 되었을때 emitter를 등록하여 데이터를 받을 준비를 하는게 좋을듯 하다.

당연하지만, Vue 컴포넌트 생명주기를 잘 고려하여야 하는게,
emit이 on보다 먼저 이루어지면 먼저 emit으로 보낸 데이터는 받을수 없다.

 

 

 

만일 모든 emit 이벤트를 받으려면 다음과 같이 작성할 수 있다.

// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )

 

 

2.5 이벤트 클리어

모든 이벤트를 클리어할 시 다음과 같이 작성한다.

// clearing all events
emitter.all.clear()

 

 

3. 사용 후기

출처:&nbsp;https://v3.ko.vuejs.org/guide/component-basics.html#%E1%84%80%E1%85%B5%E1%84%87%E1%85%A9%E1%86%AB-%E1%84%8B%E1%85%A8%E1%84%8C%E1%85%A6

 

컴포넌트 단위로 이루어진 Vue환경에서 부모자식간 데이터 전달만으로는 개발하는데에 한계가 있다.

 

만일 상호간의 컴포넌트 사이가 4촌 8촌(?)까지 가게 된다면 부모 -> 부모 -> 자식 -> 자식 이런식으로 전달해야하는데, 코드가 더 번잡해지고 디버깅이 어려워 진다.

 

그래서 이번 포스팅에서는 전역적으로 데이터를 주고받는법에 대해 작성하였는데, 

필자는 이를 사용하고나서 코드가 훨씬 깔끔해졌고, emitter의 키 값만 규칙을 가지고 잘 작성해 준다면

나중에 디버깅 할때에나, 코드를 유지보수 하는데에 있어서 보다 수월할 듯 하다.

 

 

 


#References

https://www.npmjs.com/package/mitt#usage

 

mitt

Tiny 200b functional Event Emitter / pubsub.

www.npmjs.com

 

반응형