在Vue中,组件之间的数据传递一般都是父子组件传递数据,但是在项目的实际应用当中,也存在没有关系的组件也需要传递数据,此时就不能用父子传递数据那样用props/emit的方法来实现。这个时候可以使用eventBus来实现。
eventBus相当于一个全局的事件的仓库,任何一个组件都可以去获取这个事件。
使用方式如下:
我们一个demo,有两个毫无关系的A组件和B组件,现在B组件想要使用A组件中的数据,我们可以这样使用--------
- Step1 初始化
我们可以在utils目录中创建一个eventBus.js文件
import Vue from 'vue'
export default new Vue()
- Step2 在A组件中发送数据到eventBus
EventBus.$emit(发送的事件名,传递的参数)
<template>
<div>
<h1>A 组件</h1>
<router-link to="/about">About</router-link>
</div>
</template>
<script>
import { EventBus } from "@/utils/eventBus.js";
export default {
data () {
return {}
},
beforeDestroy () {
// 将事件homeData发送到全局的eventBus中去并且将A页面的数据带过去
EventBus.$emit("homeData", 'HOME');
}
};
</script>
- Step3 在B组件中接收数据
EventBus.$on(监听的事件名, 回调函数)
<template>
<div>
<h1>当前是---About</h1>
<router-link to="/">Home</router-link>
</div>
</template>
<script>
import { EventBus } from "@/utils/eventBus.js";
export default {
data(){
return {}
},
created () {
// 监听A组件发送到全局eventBus中的事件homeData
EventBus.$on('homeData', data => {
console.log('出发on事件', data)
})
},
// 在B组件销毁之前移除监听事件
beforeDestroy() {
EventBus.$off("homeData");
}
};
</script>
以上是eventBus的简单使用的全过程,但是,如果在组件A中,发送事件EventBus.$emit()是写在created钩子函数中或者其他地方的时候,会发生在第一次触发的时候,B组件中的on事件不会被执行,这是因为:
当我们还在A组件的时候,组件B还没生成,也就是组件B中的 created中所监听的来自于A中的事件还没有被触发。这个时候当你A中emit事件的时候,B其实是没有监听到的
所以我们可以把emit事件写在 beforeDestroy 或者 destroyed中