Vue组件间数据传输---全局事件总线

1、全局事件总线(推荐)

总线:bus(暂时用x替代)

可以实现任意组件间的通信(父、子间仍然是props最方便),下面是原理图

 仍然是下面的例子

 1、首先是写让所有组件(vc)都可见的X,所有的vc都是VueComponent所new出来的,复习之前的(单文件组件)知道每个组件都是新的VueComponent,所以说不可以,记住之前的原型图,应该直接写在Vue原型对象上,他是唯一的,且vc和vm都能够访问它

下图中vc组件通过黄色的线访问vue原型对象的X

因为是在main.js引入的Vue,所以说在main.js里面操作Vue,给他加上X

 然后就可以正常在其他组件访问X

mounted是页面挂载完成自动运行

然后是考虑调用$on,$off,$emit的问题,X就是普通Object类型的对象,身上是没有$.....的方法的,然后直接x.$on因为x没有,就找到x的Object原型,仍然没有,所以说不能直接将X定义为对象

$on、$off、$emit都在Vue的原型对象上,所以说组件实例对象(this)能够直接调用$on,$off,$emit。为了X能够找到这三个方法,所以说x也应该定义为vc或者vm,这样就可以找到Vue的原型对象,然后找到Vue原型对象上的这三个方法

//回看之前57集,Demo是Vuecomponent,d就是组件实例对象即vc
const Demo = Vue.extend({})
const d = new Demo()
Vue.prototype.x = d 

但是仍然可以改进,下面是标准写法(上面是vc写法,下面是vm写法):

//beforeCreate是生命周期钩子,此时的this是当前new出来的vm
//此时模板还没有解析,数据监测和代理都没有完成,所以说这时先把原型上面需要放的放好即x
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.x= this //安装全局事件总线,this就是当前未完全体的vm
	},
})

实际上x需要写成$bus更常见,$是Api自带的无实际含义

 所以说为了实现Student向School数据学生名

 

## 全局事件总线(GlobalEventBus)

1. 一种组件间通信的方式,适用于<span style="color:red">任意组件间通信</span>。

2. 安装全局事件总线:

   ```js

   new Vue({

      ......

      beforeCreate() {

         Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm

      },

       ......

   })

   ```

3. 使用事件总线:

   1. 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的<span style="color:red">回调留在A组件自身。</span>

      ```js

      methods(){

        demo(data){......}

      }

      ......

      mounted() {

        this.$bus.$on('xxxx',this.demo)

      }

      ```

   2. 提供数据:```this.$bus.$emit('xxxx',数据)```

4. 最好在beforeDestroy钩子中,用$off去解绑<span style="color:red">当前组件所用到的</span>事件。

 2、消息订阅与发布

同样可以在组件间传输数据

1、订阅消息:消息名(的手机号)

2、发布消息:消息内容(需要发给我的内容)

 A组件内定阅一个消息demo,随后指定其回调为test

C组件发布消息名demo,携带数据666,因为A定阅了demo,所以说test会触发,666以参数的形式被传到test中,有许多消息订阅相关js库,常用为pubsub-js

 和上面全局事件总线一样,把学生名从Student传到School当中

 安装完js库后,再引入。记住School和Student当中都要引入。

上面的全局总线是在school组件挂载完毕就给$bus绑定hello事件;现在是挂载完毕了立刻去定阅一个消息。

下面是School’组件的js代码,被注释掉的是全局事件总线,注意区别

subscribe:订阅                      unsubscribe:取消订阅                                publish:发布

//hello是定阅消息名,msgName消息名(也是hello),data是接收返回数据的参数

pubsub.subscribe(‘hello’,function(msgName,data){

        函数体

})

//在组件销毁后同样需要取消定阅,beforeDestroy之前有讲解

//pubsub.unsubscribe(id)的参数是每次定阅的消息的ID(自动生成,代码中使用pubId接收此ID,取消定阅也是通过此ID)
pubsub.unsubscribe(this.pubId)

总结:接收方subscribe订阅消息,发送方publish消息。订阅和发布的消息名保持一致。订阅方需要设置回调函数,发布方需要写数据

//School当中订阅消息
mounted() {
    // console.log('School',this)
    /* this.$bus.$on('hello',(data)=>{
	       console.log('我是School组件,收到了数据',data)
        }) */
	this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
		console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
	})
},
beforeDestroy() {
	// this.$bus.$off('hello')
	pubsub.unsubscribe(this.pubId)
}
//Student当中发布消息
methods: {
	sendStudentName(){
		// this.$bus.$emit('hello',this.name)
		pubsub.publish('hello',666)
	}
}

 补充:

消息订阅如果不用箭头函数写输出的this为undefine,因为需要向vm的data传数据,所以说写成箭头函数形式,下面的不推荐

this.pubId = pubsub.subscribe('hello',function(msgName,data){
    console.log(this)//undefine
	console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值