vue-事件总线event bus

1,086 阅读1分钟

vue中的参数传递方式有

  • 父子组件中通过props,$emit互相传递
  • event bus事件总线
  • vuex 第一种局限于只能在父子组件中传递,如果要在兄弟组件之间传递就要用到事件总线event bus或者vuex来实现。这里讨论的是event bus这种实现方式。

首先创建一个简单的应用 src/router/index.js路由

import Vue from 'vue'
import Router from 'vue-router'
import Posts from '@/components/posts.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      children: [
        {path: 'posts', component: Posts}
      ]
    }
  ]
})

为了方便观察,以上实现了一个嵌套路由,helloworld页面嵌套了posts页面,我们在helloworld页面放按钮,点击按钮的时候发送数据,在posts页面接收数据。 然后创建一个event-bus.js文件,这个文件仅仅是作为导出EventBus来用。

import Vue from 'Vue'

export const EventBus = new Vue()

编辑src/components/HelloWorld.vue

<template>
  <div id="example">
    <button @click="sendMsg">send</button>
    <router-view></router-view>
  </div>
</template>

<script>
import {EventBus} from '../event-bus'
import posts from './posts.vue'

export default {
  components: {
    posts,
  },
 
  methods: {
    sendMsg () {
      EventBus.$emit('a-message', {name: 'kim', type: 'human'})
    }
  }
}
</script>
<style lang="css" scoped>
</style>

src/components/posts.vue

<template>
  <div class="">
    <div>我是提交页</div>
    <div class="">
      {{msg}}
    </div>
  </div>
</template>

<script>
import {EventBus} from '../event-bus'

export default {
  name: 'posts',

  data () {
    return {
      msg: '123'
    }
  },

  mounted () {
    EventBus.$on('a-message', (msg) => {
      console.log('receive message', msg)
      this.msg = msg.name
    })
  }
}
</script>

<style lang="css" scoped>
</style>

在posts页面msg默认是123,当点击按钮后,被更新成了kim

移除监听

如果想移除事件的监听,可以像下面这样操作:

EventBus.$off('a-message', {})

或者直接调用 EventBus.$off() 来移除所有事件频道,不需要添加任何参数 。

上面就是 EventBus 的使用方法,使用起来是简单,甚至如果使用场景够简单的话,可以直接用 this.$root.$emitthis.$root.$on 也是一样的,可以少初始化一个 Vue 。

每次使用 EventBus 时都需要在各组件中引入 event-bus.js 。事实上,我们还可以通过别的方式,让事情变得简单一些。那就是创建一个全局的 EventBus 。

全局EventBus

在main.js中创建一个EventBus,注册到Vue的prototype上

var EventBus = new Vue()
Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      return EventBus
    }
  }
})

然后可以向使用this.$route一样直接使用this.$bus

this.$bus.$emit('b-message','message from global bus')
this.$bus.$on('b-message', msg => {
	console.log('b-message',msg)
})

参考Vue事件总线(EventBus)使用详细介绍