Vue中事件总线(eventBus)的深入详解及使用

目录
  • 1.简介
  • 2.使用
    • 安装及引入
    • 在组件中使用
    • 补充:移除监听事件
  • 总结

1. 简介

Vue 组件中常见的有:父子组件通信、兄弟组件通信。而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件。

今天就来说说,如果两个页面没有任何引入和被引入关系,该如何通信呢?

如果应用程序不需要类似 Vuex 这样的库来处理组件之间的数据通信,就可以考虑 Vue 中的事件总线 ,即 eventBus 来通信。

eventBus 又称为事件总线。在 Vue 中可使用 eventBus 来作为沟通桥梁的概念,就像是所有组件共用相同的事件中心,可向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件。但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”,因此才需要更完善的 Vuex 作为状态管理中心,将通知的概念上升到共享状态层次。

2. 使用

可以声明一个全局变量来使用事件中心,但如果在使用 webpack 之类的模块系统,这显然不合适。
每次使用都手动 import 进来也很不方便,所以本文使用 vue-bus 插件。

vue-bus npm地址

vue-bus github地址

安装及引入

npm install vue-bus --save

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装 vue-bus:

// main.js
import Vue from 'vue';
import VueBus from 'vue-bus';
Vue.use(VueBus);

在组件中使用

假设有两个Vue组件需要通信 ,在 A 组件的按钮上面绑定了点击事件发送一则消息,想通知 B 组件。

// A 组件
<template>
  <div class="wrap">
    <button @click="sendMsg">触发</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      Amsg:'我是来自A组件的信息',
    }
  },
  methods:{
    sendMsg(){
      this.$bus.emit('changeMsg', this.Amsg );
      this.$bus.emit('doOnce','我只会触发一次');
    }
  },
}
</script>
// B 组件
<template>
  <div>
    <h3>{{Bmsg}}</h3>
  </div>
</template>

<script>
export default {
  data(){
    return {
      Bmsg:'我是B组件',
    }
  },
  methods:{
    getMsg(msg){
      this.Bmsg = msg;
      console.log(msg);
    }
  },
  created(){
    /*
    * 接收事件
    * 这种写法也体现了:A 组件调用 B 组件中的方法。如果只是传递数据,可参考如下简化写法:
    * this.$bus.on('changeMsg', (msg) => { this.Bmsg = msg });
	*/
    this.$bus.on('changeMsg', this.getMsg);
    // 此侦听器只会触发一次
    this.$bus.once('doOnce', (txt) => { console.log(txt) });
  },
  // 组件销毁时,移除EventBus事件监听
  beforeDestroy() {
    this.$bus.off('changeMsg', this.addTodo);
  },
}
</script>

当我们点击5次触发按钮时,效果如下:

补充:移除监听事件

为了避免在监听时,事件被反复触发,通常需要在页面销毁时移除事件监听。或者在开发过程中,由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听。

//使用方式一定义时
this.$EventBus.$off('eventName');
//使用方式二定义时
EventBus.$off('eventName');

总结

eventBus 适合小项目、数据被更少组件使用的项目,对于中大型项目数据在很多组件之间使用的情况 eventBus 就不太适用了。eventBus 其实就是一个发布订阅模式,利用 Vue 的自定义事件机制,在触发的地方通过 $emit 向外发布一个事件,在需要监听的页面,通过 $on 监听事件。

(0)

相关推荐

  • Vue组件之事件总线和消息发布订阅详解

    目录 简介 事件总线 消息的发布订阅 总结 简介 主要介绍事件总线的定义和编写方法和Vue是如何实现消息的订阅与发布的. 事件总线 事件总线是组件间通信的一种方式,适用于任意组件间的通信,比如毫不相干的两个组件.父子组件间.后代组件等等,都能通信. 事件总线有两个特性: 是一个vue组件实例或者一个vue实例,充当一个消息中转站,如果A.B组件想要通信,那么A组件存消息到中转站,B消息拿,或者反过来. 所有组件都要能获取到事件总线. 如果A.B组件间通信,如果A发送数据给B的情况下,需要以下步骤

  • vue采用EventBus实现跨组件通信及注意事项小结

    EventBus EventBus是一种发布/订阅事件设计模式的实践. 在vue中适用于跨组件简单通信,不适应用于复杂场景多组件高频率通信,类似购物车等场景状态管理建议采用vuex. 挂载EventBus到vue.prototype 添加bus.js文件 //src/service/bus.js export default (Vue) => { const eventHub = new Vue() Vue.prototype.$bus = { /** * @param {any} event

  • vue中eventbus被多次触发以及踩过的坑

    一开始的需求是这样子的,我为了实现两个页面组件之间的数据传递,假设我有页面A,点击页面A上的某一个按钮之后,页面会自动跳转到页面B,同时我希望将页面A上的某一些参数携带过去给页面B.(我知道,小参数的时候可以通过路由的params或者query去传参数,或者大型数据可以用vuex来处理,很遗憾我到现在还没有做很大型的项目,所以还没有用过vuex,接下来会学习一下.) 然后我就想,这不就是不同组件之间的数据传递问题而已吗?直接用bus 巴士事件来传递数据不就行了吗.于是,我就很愉快地进行了.关于v

  • 详解vue 组件之间使用eventbus传值

    对于前端的我们而言,并非是只有写界面才是最大的问题,很多的情况下,我们需要关注的是数据,比如js页面的数据传递等等,学习vue我们也是需要知道怎么去使用数据 当然,使用存储也是可以得,但是并非一定要缓存,当然在vue中有推荐了我们去使用vuex去数据交互,Vuex会让你的Vue代码足够灵活可控,把数据统一存入state, 只允许通过Actions触发Mutations修改.然而,有时候我们的项目并没有复杂到需要用上Vuex.,(我们也不讨论已经废除的vm.$dispatch)很多情况下我们都是需

  • Vue全局事件总线你了解吗

    全局事件总线,是组件间的一种通信方式,适用于任何组件间通信. 看下面具体的例子. 父组件:App <template> <div class="app"> <Company/> <Employee/> </div> </template> <script> import Company from "./components/Company.vue"; import Employee

  • Vue中事件总线(eventBus)的深入详解及使用

    目录 1.简介 2.使用 安装及引入 在组件中使用 补充:移除监听事件 总结 1. 简介 Vue 组件中常见的有:父子组件通信.兄弟组件通信.而父子组件通信就很简单,父组件会通过 props 向下传数据给子组件,当子组件有事情要告诉父组件时会通过 $emit 事件告诉父组件. 今天就来说说,如果两个页面没有任何引入和被引入关系,该如何通信呢? 如果应用程序不需要类似 Vuex 这样的库来处理组件之间的数据通信,就可以考虑 Vue 中的事件总线 ,即 eventBus 来通信. eventBus

  • vue中component组件的props使用详解

    本文介绍了 vue中component组件的props使用详解,分享给大家,具体如下: props使用方法 Vue.component('my-component',{ props:['message'], template:'<div class="tem1">{{message}}</div>' }); <my-component message="hello"></my-component> 注意:props 的

  • vue中v-model的应用及使用详解

    vue中经常使用到<input>和<textarea>这类表单元素,vue对于这些元素的数据绑定和我们以前经常用的jQuery有些区别.vue使用v-model实现这些标签数据的双向绑定,它会根据控件类型自动选取正确的方法来更新元素. v-model本质上是一个语法糖.如下代码<input v-model="test">本质上是<input :value="test" @input="test = $event.t

  • vue中v-text / v-html使用实例代码详解

    废话少说,代码如下所述: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue实例中的数据,事件和方法</title> </head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"><

  • vue中v-model动态生成的实例详解

    vue中v-model动态生成的实例详解 前言: 最近在做公司的项目中,有这么一个需求,每一行有一个input和一个select,其中行数是根据服务器返回的json数据动态变化的.那么问题来了,我们要怎样动态生成v-model? 现在项目做完了就整理了一下,直接贴代码了. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <

  • 在vue中安装使用vux的教程详解

    最近因为的工作的原因在弄vue,从后端弄到前端之前一直用js,现在第一次接触vue感觉还挺有意思的,就是自己太菜了,这个脑子呀....不太够用.....页面设计用了一个叫vux的东西,vux可以提供一些组件,用起来还是比较方便的,因为自己比较菜吧,所以有很多东西还是不太深入了解...比如对vux自带样式的修改..希望有大牛看到的话也可以多多指点... 今天就记录一下vux的安装使用吧...... 首先自己要先新建一个vue项目,cmd进入到项目目录下,进行安装 1.在项目目录下安装vux(也可以

  • 对vue中v-if的常见使用方法详解

    使用过Vue的小伙伴一定使用过v-if 这个属性,但是这个属性主要是来干什么的呢,他得用途是那些? 这里我总结了一下,v-if使用一般有两个场景: 1- 多个元素 通过条件判断展示或者隐藏某个元素.或者多个元素 2- 进行两个视图之间的切换 下面我写了两个例子,是Vue官方的简单实例. 第一个实例实现了 type等于不同值,A,B,C 三个元素的展示情况. 第二个例子实现了,点击按钮实现两个视图的切换. <!DOCTYPE html> <html lang="en"&

  • 对vue中methods互相调用的方法详解

    如下所示: 最近在学习vue,并用vue+vue-router+axios+elementUI做了一个pos收银系统的前端页面,但是中间遇到methods里的方法调用问题.本身源码是没有调用的,但是我想直接调用多方便,结果出错了--然后百度了一波,终于解决了~ 分享并做个笔记. delAllOrderList:function(goods) { this.tableData = []; this.totalCount = 0; this.money = 0; }, checkout:functi

  • Vue中util的工具函数实例详解

    Vue中util的工具函数,下面通过实例代码给大家介绍的非常详细,具体代码如下所示: // 防抖函数 function debounce (fn, wait) { let t return () => { let context = this let args = arguments if (t) clearTimeout(t) t = setTimeout(() => { fn.apply(context, args) }, wait) } } function flatten (arr)

  • vue中$refs的用法及作用详解

    一般来讲,获取DOM元素,需document.querySelector(".input1")获取这个dom节点,然后在获取input1的值. 但是用ref绑定之后,我们就不需要在获取dom节点了,直接在上面的input上绑定input1,然后$refs里面调用就行. 然后在javascript里面这样调用:this.$refs.input1 这样就可以减少获取dom节点的消耗了 用法如下: HTML: <div id="app"> <input

随机推荐