vue组件传值之事件总线(EventBus)
前言
最近在面试的时候,会问到一个问题就是你知道vue的事件总线吗?事件总线干嘛的?知道它的具体内容是什么吗?当我问到这些时,好多都没有听说过,有的听说过没用过,知道的不多。自己在想这就奇怪了,是做的项目不多还是项目做的只是练习的,没有接触过这个吗。今天就来简单的说说这个事件总线是个什么鬼。
用途
学过vue的都知道,vue中组件传值有父到子,子到父,甚至有父到孙。。。这些呢官方都有相应的例子来说明如何操作,那么相邻的呢也有vuex或者其他方式,假如目前的项目没有用到vuex如何解决呢,这里就要说到这个vue的事件总线了。
定义
这个定义呢,不是官方的定义,只是自己的一个理解,事件总线有称作为EventBus,其实和vuex还是有些类似的,说白了就是起到一个通信的作用,相当于一个中心,这个中心来管理事件,那么当我们需要用到的时候就向改中心发送和接受事件。所以其实用起来比vuex要方便很多,当前啦任何东西都有好有坏,事件总线就是太方便一旦事件多了就会带来难以维护的灾难。如果项目中不是太大可以采用这种方式。
使用
有两种使用方法,一个是全局的,一个是按需的,这里重点以按需的为例,全局的不做过多介绍,好多地方也不建议使用全局的。
初始化
其实事件总线就是vue的一个实例,也就是在这种情况下被称作为EventBus,让后将这个实例导出就可以使用了。定义如下:
import Vue from 'vue' export default new Vue()
我们也可以直接在main.js中直接初始化,这样初始化的就是全部的事件总线了。
// main.js Vue.prototype.$EventBus = new Vue()
现在EventBus已经创建好了,接下来就是需要再你的组件中引入,调用事件的方法就可以使用了。
发送事件
发送事件使用的就是$emit,接受两个参数,一个是事件名称,一个是参数,这里以ElementUI侧边栏菜单的折叠为例子:
<template> <div class="header"> <div class="header-logo"> <img alt="Vue logo" src="../../assets/images/common/logo.png" @click="changeCollapse"> </div> </div> </template> <script> import bus from '@/utils/eventBus.js' export default { data() { return { collapse: false } }, methods: { changeCollapse(){ this.collapse = !this.collapse bus.$emit('collapse', this.collapse) } } } </script>
上面的例子就是当我们点击log的时候来切换侧边栏菜单的折叠的,这是在顶部组件中,那么要控制侧边栏组件的折叠显然直接是不可能的,所以这里就使用了vue事件总线来实现的。上面的发送事件也很简单,就是事件名称为collapse,参数就是当前data中定义的collapse了。
<template> <div class="sidebar"> <el-scrollbar class="scroll-wrapper"> <el-menu class="sidebar-el-menu" :default-active="$route.path" :collapse="collapse" unique-opened router> <subItem :items="items" :collapse="collapse" /> </el-menu> </el-scrollbar> <div class="slideIn" @click="changeCollapse">||</div> </div> </template> <script> import bus from "@/utils/eventBus.js" import subItem from "./subitem" export default { props:['items'], data() { return { collapse: false } }, created() { bus.$on("collapse", msg => { this.collapse = msg }) }, methods: { changeCollapse() { this.collapse = !this.collapse bus.$emit("collapse", this.collapse) } } } </script>
移除事件
移除事件可使用$off,如果想单独移除某一个事件的监听就可以使用第一个参数即为事件名称,如果想全部移除不带任何参数即可。例子如下:
<script> import bus from "@/utils/eventBus.js" export default { methods: { handleClick() { bus.$off("collapse", {}) // 移除单个事件 // bus.$off() // 移除全部事件 } } } </script>
总结
总体上来说,使用时很方便的,记住两个就行,一个是发送事件emit,一个是接受事件emit,一个是接受事件of,对于兄弟组件或者没有任何包含关系的组件通信的话使用EventBus简便快捷。