본문 바로가기

개발/FRONT

[Vue3] Composition API 환경 컴포넌트 간 이벤트 전달하기

728x90

 

 

 

Vue3 환경에서 서로 다른 컴포넌트 간의 이벤트를 전달하기 위해 사용했던 방법이다.

 

사용 이유


 

나의 경우에는 상단의 알림 다이얼로그에서 보여지는 알람들 중, 읽지 않은 것은 별도의 표시를 해주고 있다.

또한 알림 리스트 페이지를 따로 구현해서 전체 알림을 조회할 수 있는 페이지가 별도로 구현되어있었는데,

 

다이얼로그에서 알림을 클릭해 상세 페이지로 이동할 때에는 문제가 없었지만, 

리스트 페이지에서 상세페이지로 이동했을 때,

알림 다이얼로그 페이지는 별도의 페이지로 구현되어 있기 때문에, 해당 이벤트를 인지할 수 없어서

reactive하게 알림 다이얼로그 데이터를 최신화할 수없었다.

 

요약

주체가 알림 다이얼로그 페이지일 때,

알림 다이얼로그 -> 상세 페이지 인지 가능

알림 리스트 페이지 -> 상세 페이지 인지 불가능

 


 

mitt

 

먼저 이벤트버스(eventBus) 기능을 사용하려고 했지만, 찾아보니 Vue3에서는 지원하지 않는 기능이라는 걸 알게 되었다.

 

그래서, 이벤트버스를 대신할 서드파티 라이브러리를 찾았고, 그게 mitt다.

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

 

mitt

Tiny 200b functional Event Emitter / pubsub.. Latest version: 3.0.1, last published: 5 months ago. Start using mitt in your project by running `npm i mitt`. There are 2085 other projects in the npm registry using mitt.

www.npmjs.com

npm i mitt   -- 설치

 

 

다음은 해당 플러그인을 사용할 방법이다.

 

 

 

1.

main.js (상위 컴포넌트 globalProperties 설정)

...
import mitt from "mitt";	// add
...


const app = createApp(App)
const emitter = mitt()		// add

...
...
app.config.globalProperties.emitter = emitter; // add
..
..

app.mount('#app')

 

 

2.

이벤트 내보낼 페이지 설정

index.vue

 

트리거가 발생했다는 인지가 필요한 시점에 

emitter.emit() 함수를 통해 이벤트 명과 전달할 데이터를 넘겨주면 된다.

<script setup>
// Composition API 용 emitter 설정
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;


// 1. 리스트 페이지에서 상세 페이지로 네비게이팅 될 때, 읽음 처리를 하는 API 실행
// 2. API 실행 후, return 되는 response 값을 담아 event 방출
// 3. 상세 페이지로 이동
const goDetailPage = data => {
    notiStore.notiUpdate({
      id : id,
      confirmAt : 'Y'
    }).then(response => {
    	// 이벤트 명 : updateNotiEvent
        // 전달 데이터 : response.result  :: success / fail
      emitter.emit("updateNotiEvent",response.result);
    })
  
	//페이지 이동
  router.push(
    {
      name: 'page-name', params:{id:id }
    }
  )
}

</script>

 

 

3.

이벤트 수신할 상단바 페이지 설정

TopNaviBar.vue

 

<script setup>
// Composition API 용 emitter 설정
const internalInstance = getCurrentInstance();
const emitter = internalInstance.appContext.config.globalProperties.emitter;


//1. 이벤트가 발생했을 때, 해당 이벤트 이름으로 이벤트 수신
//2. 결과 데이터 수신 후, 저장완료됐다면 rendering
watchEffect(()=>{
  emitter.on("updateNotiEvent",result => {
    if(result === "success"){
        alarmList();
    }
  })
})

</script>

 

 

각 컴포넌트가 부모 자식 관계가 아닌 컴포넌트 사이에서 이벤트를 통신이 필요할 때가 있어서 구현해보았다. 

 

 

728x90