我有一个Vue应用程序(基本上是一个视频播放器),它使用EventBus跨通常不容易通信的组件进行通信。当我开发视频播放器时,这种方法工作得很好,但现在我使用Rollup将其捆绑在一起,当我尝试将视频播放器的多个实例放在同一页面上时,一个实例发送的任何事件也将被应用程序的所有其他实例拾取。
现在回过头来看,我明白了为什么人们似乎不喜欢EventBus,但我找不到一个很好的解决方案来改进或取代它。我不能动态地命名EventBus实例,因为这样我的应用程序的其余部分就不会被告知新的名称。我甚至不能在我的EventBus侦听器中使用像videoId这样的东西来控制唯一性,因为如果一个视频多次出现在同一个页面上,我就会遇到同样的问题。
一些帖子建议使用VueX,但我的应用程序不需要是有状态的,它看起来也不像是事件和监听器的替代品(尽管在这一点上我可能是错的)。对于比我需要的更多的功能,这似乎有很大的开销。再说一次,我可能错了。
我试图删除尽可能多的不相关的代码,但给出了我是如何实现我的EventBus的想法:event-bus.js
import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;MediaPlayer.vue
<template>
<div>
<div>
<div id='media-player'>
<end-screen v-if="videoIsFinished"/>
<tap-video
ref="tapVideoRef"
:source='sourceUrl'
:videoId='videoId'
@videoEndHandler='videoEndHandler'
>
</tap-video>
<div id="control-bar-container">
<transition name="slide-fade">
<div v-show='(showControls || !playing)' >
<media-controls
:playing="playing"
:videoLength="videoLength"
/>
</div>
</transition>
</div>
</div>
</div>
</div>
</template>
<script>
import TapVideo from './TapVideo.vue';
import EventBus from './event-bus';
export default {
data (){
return{
playing: false,
showControls: false,
videoLength: 0,
tapVideoRef: null
}
},
mounted() {
this.tapVideoRef = this.$refs.tapVideoRef;
EventBus.$on('videoLoaded', videoLength => {
this.videoLength = videoLength;
});
EventBus.$on('playStateChange', playing => {
this.onPlayStateChange(playing);
});
},
beforeDestroy() {
EventBus.$off(['playStateChange','closeDrawer']);
},
props: ['sourceUrl', 'platformType', 'videoId'],
}
</script>发布于 2021-08-03 21:11:15
如果有人遇到这个问题,我找到了一个适合我的解决方案。感谢@ChunbinLi为我指明了正确的方向-他们的解决方案确实有效,但到处传递道具有点笨拙。
相反,我使用了Vue:https://v3.vuejs.org/guide/component-provide-inject.html支持的提供/注入模式
一些最小的相关代码:
最高级别的祖父母将提供EventBus,
Grandparent.vue
export default {
provide() {
return {
eventBus: new Vue()
}
}
}那么任何后代都有能力注入该总线,
Parent.vue
export default {
inject: ['eventBus'],
created() {
this.eventBus.$emit('neededEvent')
}
}Child.vue
export default {
inject: ['eventBus'],
created(){
this.eventBus.$on('neededEvent', ()=>{console.log('Event triggered!')});
}
}这仍然是一个全局EventBus,所以事件的方向性和父关系很容易,只要所有通信的组件都是“提供”总线的组件的后代。
https://stackoverflow.com/questions/68568497
复制相似问题