文章目录
组件之间的传参方法有:父传子、子传父、缓存、vuex、ref、事件总线。接下来就是对事件总线的介绍
一、什么是事件总线
事件总线可以作为组件沟通的桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行地通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的灾难,因此才需要更完善的Vuex作为状态管理中心,将通知的概念上升到共享状态层次。(也就是说:简单的两三个组件之间需要传参时使用事件总线还可以,但是一旦多了就不好管理。所以,当开发大型项目并且页面之间传递比较复杂时,还是使用vuex比较合适)
二、uniapp中的事件总线
1、监听事件 uni.$on()
uni.$on(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
当然,该方法中的回调函数不使用匿名函数也是可以的
代码示例:
// 注册事件
uni.$on('updata',(data)=>{
console.log('现在在使用事件总线进行数据传输,从son2传到son1的:'+data.msg);
this.msg = data.msg
})
// 下面这种情况并不会使vue实例中的msg进行改变,原因是this的原因
console.log(this); // 这个this指向的是 VueComponent {}
// uni.$on('updata',function(data){
// console.log(this); // 这个this指向的是 Vue {}
// console.log('现在在使用事件总线进行数据传输,从son2传到son1的:'+data.msg);
// this.msg = data.msg
// })
2、触发事件 uni.$emit()
在uni中可以通过uni.$emit(eventName,OBJECT)来触发全局的自定事件。附加参数都会传给监听器回调。
<button type="default" @click="getMsg"> 点击传参updata1 </button>
getMsg(){
// 事件调用
uni.$emit('updata',{msg:'我是参数,传到son1'})
},
3、只监听一次 uni.$once()
uni.$once(eventName,callback)
监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器。
// 只监听一次
uni.$once('updata2',(data)=>{
console.log('事件总线2:' + data.msg);
})
4、移除监听 uni.$off()
uni.$off([eventName, callback]) 移除全局自定义事件监听器。
<button type="default" @click="off"> 点我解除事件总线1 </button>
off(){
// 解除事件
uni.$off('updata')
}
注意事项
- 如果没有提供参数,则移除所有的事件监听器;
- 如果只提供了事件,则移除该事件所有的监听器;
- 如果同时提供了事件与回调,则只移除这个回调的监听器;
- 提供的回调必须跟$on的回调为同一个才能移除这个回调的监听器;
5、注意事项
- uni. e m i t 、 u n i . emit、 uni. emit、uni.on 、 uni. o n c e 、 u n i . once 、uni. once、uni.off 触发的事件都是 App 全局级别的,跨任意组件,页面,nvue,vue 等
- 使用时,注意及时销毁事件监听,比如,页面 onLoad 里边 uni. o n 注册监听, o n U n l o a d 里边 u n i . on 注册监听,onUnload 里边 uni. on注册监听,onUnload里边uni.off 移除,或者一次性的事件,直接使用 uni.$once 监听
三、vue中的事件总线
在vue中也可以通过EventBus(事件总线)的方式进行兄弟组件的传值,具体的操作,大家可以参照文档使用。
文档中的接好已经非常详细了,这里只想说一下为什么要重新定义一个新的vue实例:因为在原有的vue实例中,挂载了很多的东西,例如DOM、BOM等以及一些其他的方法,不利于我们对事件总线进行使用。新建一个vue实例就是为了将事件总线的使用单拿出来,这样维护起来更加方便。