이전 포스팅에서 상위 컴포넌트와 하위 컴포넌트 간의 데이터 통신에 대해 다룬적이 있다.
this.$emit과 props다.
이건 상위,하위 컴포넌트 간의 데이터 통신인데, 상 하위 관계가 아닌 완전히 다른 컴포넌트 간의 데이터 통신은 어떻게 할까?
이번 포스팅 주제인 Event Bus에 대해 알아보자.
// utils/bus.js
import Vue from 'vue';
export default new Vue();
우선 이벤트를 받고 전달하는 용도로 bus.js 파일을 생성한다.
Vue객체 내 $emit과 $on을 사용하기 위함이다.
이벤트 전달을 위해 $emit을 이용하여 이벤트를 생성하고,
이벤트를 받기 위해 $on을 이용하여 이벤트 구독을 한다.
// A.vue
<template>
<div>
<button @click="sendEvent">send</button>
</div>
</template>
<script>
import bus from '../utils/bus.js';
export default {
methods: {
sendEvent() {
bus.$emit('send', 1);
}
}
}
</script>
// B.vue
<template>
<div>
{{ receivedData }}
</div>
</template>
<script>
import bus from '../utils/bus.js';
export default {
data() {
return {
receivedData: ''
}
},
methods: {
receiveEvent() {
bus.$emit('send', data => {
this.receivedData = data;
});
}
}
}
</script>
이 원리를 이용하여 로딩 스피너를 구현할 수 있다.
// NewsView.vue
<template>
<div>
<list-item />
</div>
</template>
<script>
import ListItem from '../components/ListItem.vue';
import bus from '../utils/bus.js';
export default {
components: {
ListItem
},
created() {
bus.$emit('start:spinner');
setTimeout(() => {
this.$store.dispatch('FETCH_NEWS')
.then(() => {
console.log('fetched');
bus.$emit('end:spinner');
})
.catch(err => {
console.log(err);
});
bus.$emit('end:spinner');
}, 3000);
}
};
</script>
// App.vue
<template>
<div id="app">
<tool-bar />
<main>
<transition :name="transitionName">
<router-view></router-view>
</transition>
</main>
<spinner :loading="loadingStatus"/>
</div>
</template>
<script>
import ToolBar from './components/ToolBar.vue';
import Spinner from './components/Spinner.vue';
import bus from './utils/bus.js';
export default {
components: {
ToolBar,
Spinner
},
data() {
return {
transitionName: "",
loadingStatus: false
};
},
methods: {
startSpinner() {
this.loadingStatus = true;
},
endSpinner() {
this.loadingStatus = false;
}
},
created() {
bus.$on('start:spinner', this.startSpinner);
bus.$on('end:spinner', this.endSpinner);
},
beforeDestroy() {
bus.$off('start:spinner', this.startSpinner);
bus.$off('end:spinner', this.endSpinner);
}
}
</script>