视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue非父子组件传值和事件总线(eventbus)的使用方式介绍
2020-11-27 19:28:15 责编:小采
文档


本篇文章给大家带来的内容是关于vue非父子组件传值和事件总线(eventbus)的使用方式介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

先说一下什么是事件总线,其实就是订阅发布者模式;

比如有一个bus对象,这个对象上有两个方法,一个是on(监听,也就是订阅),一个是emit(触发,也就是发布),我们通过on方法去监听某个事件,再用emit去触发这个事件,同时调用on中的回调函数,这样就完成了一次事件触发;

这是一种设计模式,和语言没有关系;

如果不太了解什么是订阅发布者模式,请移步看这篇文章JavaScript设计模式--观察者模式(发布者-订阅者模式)

在实际开发中,往往最麻烦的就是各种组件之间的传值问题;如果利用事件总线就会让这件事情变得很简单;

vue自带事件总线的短板

我们都知道在vue被实例化之后,他就具备了充当事件总线对象的能力,在他上面挂了两个方法,是$emit和$on;

而vue文档说的很明白,$emit会触发当前实例上的事件,附加参数都会传给回调;

由于在实际工作中,我们都是以组件的形式开发,每个组件就是一个实例;

所以利用vue自带的总线能力有很大的局限性,最多只能从子组件触发到父组件中,而不能在非父子组件之间传值;

所以这时,我们就需要有一个全局的事件总线对象,让我们挂载监听事件和触发事件;

举个例子,子组件向父组件传值;父组件向子组件传值很简单,我们这里不说
// 子组件中
<template>
 <div>
 <span>{{child}}</span>
 <input type="button" value="点击触发" @click="send">
 </div>
</template>
<script>
 export default {
 data () {
 return {
 child: '我是子组件的数据'
 }
 },
 methods: {
 send () {
 // 如果传多个值就用逗号隔开 a, b, c
 this.$emit('fromChild', this.child)
 }
 }
 }
</script>
// 父组件
<template>
 <div>
 <span>{{name}}</span>
 // 在父组件中监听 fromChild事件
 <child @fromChild="onFromChild"></child>
 </div>
</template>
<script>
 import child from './child'
 export default {
 components: {
 child
 },
 data () {
 return {
 name: ''
 }
 },
 methods: {
 onFromChild: function (data) {
 // data就是子组件传过来的值
 // 如果传过来多个值就用逗号隔开去接收 data1, data2, data3
 this.name = data
 }
 }
 }
</script>

实现全局事件总线对象的几种方式

方式一,也是我自己使用的方式(推荐使用,简单)

大概思路是 :在main.js,也就是入口文件中,我们在vue的原型上添加一个bus对象;

具体实现方式如下:

下面的组件A和组件B可以是项目中任意两个组件

//在mian.js中
Vue.prototype.bus = new Vue() //这样我们就实现了全局的事件总线对象

//组件A中,监听事件
this.bus.$on('updata', function(data) {
 console.log(data) //data就是触发updata事件带过来的数据
})

//组件B中,触发事件
this.bus.$emit('updata', data) //data就是触发updata事件要带走的数据

方式二,稍微有点麻烦,但也很容易理解

大概的实现思路: 新建一个bus.js文件, 在这个文件里实例化一下vue;然后在组件A和组件B中分别引入这个bus.js文件,将事件监听和事件触发都挂到bus.js这个实例上,这样就可以实现全局的监听与触发了

写个例子
bus.js文件
// bus.js文件
import Vue from 'vue'
export default new Vue()
组件A
// 组件A ,监听事件send
<template>
 <div>
 <span>{{name}}</span>
 </div>
</template>
<script>
 import Bus from './bus.js'
 export default {
 data () {
 return {
 name: ''
 }
 },
 created() {
 let _this = this
 // 用$on监听事件并接受数据
 Bus.$on('send', (data) => {
 _this.name = data
 console.log(data)
 })
 },
 methods: {}
 }
</script>

组件B

// 组件B, 触发事件send
<template>
 <div>
 <input type="button" value="点击触发" @click="onClick">
 </div>
</template>
<script>
 import Bus from './bus.js'
 export default {
 data () {
 return {
 elValue: '我是B组件数据'
 }
 },
 methods: {
 // 发送数据
 onClick() {
 Bus.$emit('send', this.elValue)
 }
 }
 }
</script>

这样我们就完成了一个简单非父子组件之间的传值。

下载本文
显示全文
专题