[운영환경]
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. 사용 후기
컴포넌트 단위로 이루어진 Vue환경에서 부모자식간 데이터 전달만으로는 개발하는데에 한계가 있다.
만일 상호간의 컴포넌트 사이가 4촌 8촌(?)까지 가게 된다면 부모 -> 부모 -> 자식 -> 자식 이런식으로 전달해야하는데, 코드가 더 번잡해지고 디버깅이 어려워 진다.
그래서 이번 포스팅에서는 전역적으로 데이터를 주고받는법에 대해 작성하였는데,
필자는 이를 사용하고나서 코드가 훨씬 깔끔해졌고, emitter의 키 값만 규칙을 가지고 잘 작성해 준다면
나중에 디버깅 할때에나, 코드를 유지보수 하는데에 있어서 보다 수월할 듯 하다.
#References
https://www.npmjs.com/package/mitt#usage
'SPA Framework > Vue' 카테고리의 다른 글
[Vue/Electron ISSUE] 외부 모듈 Cannot find module 문제 (0) | 2022.09.26 |
---|---|
Vue에서 v-model의 동작방식에 대해 (v-model, :value, @input...) (0) | 2022.04.08 |
Vue에서 jQuery events 잡기 (0) | 2022.04.04 |