Vue--事件总线

电玩女神 2022-12-28 06:20 319阅读 0赞

原文网址:Vue—事件总线_IT利刃出鞘的博客-CSDN博客

其他网址

Vue事件总线(EventBus)使用详细介绍 - 知乎
vue 事件总线EventBus的概念、使用以及注意点 - 简书

简易使用Vue中的中央事件总线(eventBus)

API — Vue.js 事件

简介

父子组件通信与兄弟组件通信

vue组件非常常见的有父子组件通信,兄弟组件通信。
父子组件通信:方法有很多,比如:父组件通过 props 向下传数据给子组件,子组件通过 $emit 告诉父组件。更多方法见:Vue基础系列—双向绑定_feiying0canglang的博客-CSDN博客
兄弟组件通信:如果两个页面没有任何引入和被引入关系,需要额外的组件来通信,如:事件总线、Vuex

事件总线概述

EventBus 又称为事件总线。在Vue中可以使用 EventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。

EventBus若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。

优点

  • 解决了多层组件之间繁琐的事件传播。
  • 使用原理十分简单,代码量少

缺点

  • 大家都知道vue是单页应用,如果你在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。
  • 如果业务有反复操作的页面,EventBus在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理EventBus在项目中的关系。通常在vue页面销毁时,同时移除EventBus事件监听。
  • 由于是都使用一个Vue实例,所以容易出现重复触发的情景:两个页面都定义了同一个事件名,并且没有用$off销毁(常出现在路由切换时)。

详述

创建事件

首先需要创建事件总线并将其导出,以便其它模块可以使用或者监听它。

法1、非全局事件组件

新建EventBus.js

  1. import Vue from 'vue'
  2. export const EventBus = new Vue()

法2、全局事件组件

在项目中的 main.js 初始化 EventBus。在main.js添加如下一行:

  1. Vue.prototype.$EventBus = new Vue()

示例:

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. import router from './router'
  6. Vue.config.productionTip = false
  7. Vue.prototype.$EventBus = new Vue();
  8. /* eslint-disable no-new */
  9. new Vue({
  10. el: '#app',
  11. router,
  12. components: { App },
  13. template: '<App/>'
  14. })

用法

组件发送事件:this.$EventBus.$emit(…)
组件发送事件:this.$EventBus.$emit(…)

下边这样写是不可以的

  1. // The Vue build version to load with the `import` command
  2. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
  3. import Vue from 'vue'
  4. import App from './App'
  5. import router from './router'
  6. Vue.config.productionTip = false
  7. let EventBus = new Vue();
  8. /* eslint-disable no-new */
  9. new Vue({
  10. el: '#app',
  11. router,
  12. EventBus,
  13. components: { App },
  14. template: '<App/>'
  15. })

移除事件

一般在销毁组件(也就是离开组件)时移除事件。

  1. beforeDestroy(){
  2. EventBus.$off("eventName")
  3. }

移除的方法

EventBus.$off() //移除EventBus所有事件监听器
EventBus.$off(‘eventName’) //移除’eventName’事件所有监听器
EventBus.$off(‘eventName’, callback) //只移除这个回调的监听器。

实例

本文父组件:CompA.vue,子组件1:ChildOne.vue,子组件2:ChildTwo.vue。子组件1发送事件给父组件和子组件2。

router/index.js

  1. import Vue from 'vue'
  2. import Router from 'vue-router'
  3. import CompA from "@/components/CompA";
  4. Vue.use(Router)
  5. export default new Router({
  6. routes: [
  7. {
  8. path: '/compA',
  9. name: 'compA',
  10. component: CompA,
  11. }
  12. ],
  13. })

1.创建EventBus

新建EventBus.js

  1. import Vue from 'vue'
  2. export const EventBus = new Vue()

2.发送事件

components/ChildOne.vue

  1. <template>
  2. <div class="childOne">
  3. <h1>childOne</h1>
  4. <button @click="sendEvent2CompA">发送事件给父组件(CompA)</button>
  5. <button @click="sendEvent2ChildTwo">发送事件给兄弟组件(ChildTwo)</button>
  6. </div>
  7. </template>
  8. <script>
  9. import {EventBus} from "./EventBus"
  10. export default {
  11. data() {
  12. return {
  13. count1: 0,
  14. count2: 0,
  15. }
  16. },
  17. methods:{
  18. sendEvent2CompA() {
  19. this.count1++;
  20. EventBus.$emit("compA", "compA事件触发次数:" + this.count1)
  21. },sendEvent2ChildTwo() {
  22. this.count2++;
  23. EventBus.$emit("childTwo", "childTwo事件触发次数:" + this.count2)
  24. }
  25. }
  26. }
  27. </script>
  28. <style scoped>
  29. </style>

3.接收事件

父组件:components/CompA.vue

  1. <template>
  2. <div class="compA">
  3. <h1>compA</h1>
  4. compA收到的事件内容:{
  5. {msg}}<hr>
  6. <child-one></child-one><hr>
  7. <child-two></child-two>
  8. </div>
  9. </template>
  10. <script>
  11. import {EventBus} from "./EventBus"
  12. import ChildOne from "@/components/ChildOne";
  13. import ChildTwo from "@/components/ChildTwo";
  14. export default {
  15. components: {ChildOne, ChildTwo},
  16. data() {
  17. return {
  18. msg: "",
  19. }
  20. },
  21. mounted() {
  22. EventBus.$on("compA", (payload1)=> {
  23. this.msg = payload1;
  24. })
  25. }
  26. }
  27. </script>
  28. <style scoped>
  29. </style>

子组件2:components/ChildTwo.vue

  1. <template>
  2. <div class="childTwo">
  3. <h1>childTwo</h1>
  4. childTwo收到的事件内容:{
  5. {msg}}
  6. </div>
  7. </template>
  8. <script>
  9. import {EventBus} from "./EventBus"
  10. export default {
  11. data() {
  12. return {
  13. msg: "",
  14. }
  15. },
  16. mounted() {
  17. EventBus.$on("childTwo", (payload1)=> {
  18. this.msg = payload1;
  19. })
  20. }
  21. }
  22. </script>
  23. <style scoped>
  24. </style>

4.销毁事件

本处省略先不写。

5.测试

访问:http://localhost:8080/#/compA

20201216003332929.gif

发表评论

表情:
评论列表 (有 0 条评论,319人围观)

还没有评论,来说两句吧...

相关阅读