首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同一Vue应用程序的多个实例的唯一EventBus

同一Vue应用程序的多个实例的唯一EventBus
EN

Stack Overflow用户
提问于 2021-07-29 07:42:34
回答 1查看 33关注 0票数 0

我有一个Vue应用程序(基本上是一个视频播放器),它使用EventBus跨通常不容易通信的组件进行通信。当我开发视频播放器时,这种方法工作得很好,但现在我使用Rollup将其捆绑在一起,当我尝试将视频播放器的多个实例放在同一页面上时,一个实例发送的任何事件也将被应用程序的所有其他实例拾取。

现在回过头来看,我明白了为什么人们似乎不喜欢EventBus,但我找不到一个很好的解决方案来改进或取代它。我不能动态地命名EventBus实例,因为这样我的应用程序的其余部分就不会被告知新的名称。我甚至不能在我的EventBus侦听器中使用像videoId这样的东西来控制唯一性,因为如果一个视频多次出现在同一个页面上,我就会遇到同样的问题。

一些帖子建议使用VueX,但我的应用程序不需要是有状态的,它看起来也不像是事件和监听器的替代品(尽管在这一点上我可能是错的)。对于比我需要的更多的功能,这似乎有很大的开销。再说一次,我可能错了。

我试图删除尽可能多的不相关的代码,但给出了我是如何实现我的EventBus的想法:event-bus.js

代码语言:javascript
复制
import Vue from 'vue';

const EventBus = new Vue();

export default EventBus;

MediaPlayer.vue

代码语言:javascript
复制
<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>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-03 21:11:15

如果有人遇到这个问题,我找到了一个适合我的解决方案。感谢@ChunbinLi为我指明了正确的方向-他们的解决方案确实有效,但到处传递道具有点笨拙。

相反,我使用了Vue:https://v3.vuejs.org/guide/component-provide-inject.html支持的提供/注入模式

一些最小的相关代码:

最高级别的祖父母将提供EventBus,

Grandparent.vue

代码语言:javascript
复制
export default {
   provide() {
    return {
      eventBus: new Vue()
    }
  }
}

那么任何后代都有能力注入该总线,

Parent.vue

代码语言:javascript
复制
export default {
  inject: ['eventBus'],
  created() {
    this.eventBus.$emit('neededEvent')
  }
}

Child.vue

代码语言:javascript
复制
export default {
  inject: ['eventBus'],
  created(){
    this.eventBus.$on('neededEvent', ()=>{console.log('Event triggered!')});
  }
}

这仍然是一个全局EventBus,所以事件的方向性和父关系很容易,只要所有通信的组件都是“提供”总线的组件的后代。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68568497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档