Vue 3 애플리케이션에서 여러 컴포넌트에서 동일한 컴포넌트를 사용하면서 mitt를 활용한 이벤트 핸들러가 중복 실행되는 문제를 해결하는 방법을 소개합니다.
이 글에서는 전역 이벤트 버스를 사용하여 이벤트 리스너가 한 번만 등록되도록 하는 방법을 설명합니다.
문제상황
여러 컴포넌트(order.vue, rfOrder.vue, marketWatch_spot.vue, marketWatch_exchange.vue)에서 동일한 컴포넌트(currencyMaster.vue)를 사용하고 있습니다.
mitt를 사용하여 이벤트(FAReceive)를 관리하는데, 각 컴포넌트가 마운트될 때마다 동일한 이벤트 리스너가 중복 등록되어 이벤트 발생 시 핸들러가 여러 번 호출되는 문제가 발생했습니다.
문제 해결 방법
이 문제를 해결하기 위해 window 전역 객체를 사용하여 이벤트 리스너가 한 번만 등록되도록 상태를 관리합니다.
해결전 코드
//-- main.js
import { createApp } from 'vue';
import App from './App.vue';
import mitt from 'mitt';
// mitt 인스턴스를 window 객체에 등록
window.emitter = mitt();
const app = createApp(App);
app.mount('#apptr');
//-- currencyMaster.vue
<template>
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
onMounted(() => {
window.emitter.on('FAReceive', handleFAReceive);
});
</script>
//-- order.vue
<template>
<currencyMaster ref="currencyMaster">
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
import currencyMaster from './currencyMaster.vue'
</script>
//-- rfOrder.vue
<template>
<currencyMaster ref="currencyMaster">
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
import currencyMaster from './currencyMaster.vue'
</script>
//-- marketWatch_spot.vue
<template>
<currencyMaster ref="currencyMaster">
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
import currencyMaster from './currencyMaster.vue'
</script>
//-- marketWatch_exchange.vue
<template>
<currencyMaster ref="currencyMaster">
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
import currencyMaster from './currencyMaster.vue'
</script>
해결방법
1. mitt 이벤트 버스 설정
먼저, mitt를 사용하여 전역 이벤트 버스를 설정합니다. 이를 위해 main.js 파일에서 mitt 인스턴스를 window 객체에 등록합니다.
window 전역변수를 이용하여 이벤트가 등록되었는지 확인합니다.
//-- main.js
import { createApp } from 'vue';
import App from './App.vue';
import mitt from 'mitt';
// mitt 인스턴스를 window 객체에 등록
window.emitter = mitt();
const app = createApp(App);
app.mount('#apptr');
2. 이벤트 리스너 상태 관리
currencyMaster.vue 컴포넌트에서 전역 변수를 사용하여 이벤트 리스너가 이미 등록되었는지 확인하고, 한 번만 등록되도록 구현합니다.
//-- currencyMaster.vue
<template>
<div>
</div>
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue';
// 전역 변수를 사용하여 리스너 등록 상태를 추적
if (!window.isFAReceiveListenerRegistered) {
window.isFAReceiveListenerRegistered = false;
}
const handleFAReceive = (data) => {
console.log('FAReceive event received:', data);
};
onMounted(() => {
if (!window.isFAReceiveListenerRegistered) {
window.emitter.on('FAReceive', handleFAReceive);
window.isFAReceiveListenerRegistered = true;
}
});
</script>
이 코드는 window.isFAReceiveListenerRegistered 변수를 사용하여 이벤트 리스너가 이미 등록되었는지 확인합니다. 등록되지 않았다면, 이벤트 리스너를 등록하고 변수를 true로 설정합니다.
위와 같이 하면 emitter 겍체의 FAReceive 이벤트 array 는 1개값만 나오며 1개의 이벤트만 받습니다.
'프로그래밍 > Js' 카테고리의 다른 글
vue3 부모->자식 자식->부모 데이터 전달방법 (0) | 2024.08.12 |
---|---|
vue3 pinia 메모리 누수 증가 개선코드 (0) | 2024.08.02 |
[vue3] Vue3 프로젝트에서 웹과 모바일 연동 문제 해결 emitter 문제 (0) | 2024.05.29 |
앱에서 input 클릭시 뷰포트 안으로 들어오게 하는 방법 (0) | 2024.05.08 |
[html] inputmode 를 이용하여 상황에 맞는 키패드 보여주기 (0) | 2023.10.23 |