0
点赞
收藏
分享

微信扫一扫

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信


全局事件总线原理分析

前提:x是个组件,不属于任何一个组件

要求:A组件想要收到别的组件给的信息

在A组件里给x绑定个自定义事件​​demo​​,对应的回调函数就留在A中

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js


D组件想给A传点数据,就可以这样做:

在D组件里,写点代码触发x身上的demo事件,并且传点数据过去(666),

x身上的demo事件被触发了,demo事件的回调函数就得执行,而这个回调函数在A组件里面,那之前D组件传的数据666,就在A组件里面

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_02

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_03

要求:B组件想收到点别的组件传的数据,

在B组件里写点代码,给x组件绑定个事件test,回调函数留在B组件中

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_04


当D组件给B组件传数据时,

在D组件中写点代码,触发x组件身上的test事件,带个数据8过去,

那D组件身上的test事件就会被触发,那test事件所对应的回调就会被执行,而这个回调函数在B中,B就会接收到test事件携带的数据8

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_05


整个应用里,各种绑定事件,触发事件,都靠x组件,

以上就是事件总线的原理图

要求:

  1. 所有人都能看到x
  2. x能调用​​$on​​,绑定自定义事件
    x能调用​​$off​​,解绑事件
    x能调用​​$emit​​,触发事件

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_06

1. 所有人都能看到x

所有组件都能看到x组件

直接把x加到vue的原型上就好了,因为​​VueComponent.prototype.__proto__ === Vue.prototype​​,把x加到vue的原型上,VC的实例也能访问到,组件也能访问到

​​[vue] 一个重要的内置关系 VueComponent.prototype.proto === Vue.prototype​​

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_07


举例:

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_事件总线_08


[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_09

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_10


[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_事件总线_11

2. x能调用​​$on​​​,​​$off​​​,​​$emit​

​$on​​​,​​$off​​​,​​$emit​​在Vue的Prototype上

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_12

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_App_13


x想使用Vue原型上的这三个方法,x要么是vm(vue实例对象),要么是vc(组件实例对象)

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_App_14


d就是vc,就可以调用到​​$on​​​,​​$off​​​,​​$emit​

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_App_15


[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_16

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_vue.js_17

这样就简单实现了Student给School传递数据,兄弟组件可以通信了

[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信_Vue_18


一般来说,不叫x,叫$bus

安装全局事件总线

import Vue from 'vue'

import App from './App'
import VueRouter from 'vue-router'

// VueRouter引入到Vue类中
Vue.use(VueRouter)

Vue.config.productionTip = false

new Vue({
el:'#app',
render:h=>h(App),
beforeCreate () {
// this就是Vue实例对象vm ,vm上有$on,$emit,$off,直接用它就行
Vue.prototype.$bus = this // 安装全局事件总线
}
})

代码

Student.vue

<template>
<div class="student">
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="SendStudentName">把Student数据给School</button>
</div>
</template>

<script>
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
number:0
}
},
methods: {
SendStudentName(){
// 触发x组件身上的自定义事件hello,并传个数据过去
this.$bus.$emit('hello',666)
}
}
}
</script>

<style scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>

School.vue

<template>
<div class="school">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>

<script>
export default {
name:'School',

data() {
return {
name:'尚硅谷',
address:'北京',
}
},
// // School组件只要挂载完毕,马上给$bus绑定个自定义事件hello
mounted () {
// 给$bus绑定个自定义事件hello,回调函数在School组件里
this.$bus.$on('hello',(data)=>{
console.log('我是School组件,我收到了数据:',data);

})
},
// 在销毁前解绑$bus
beforeDestroy () {
this.$bus.off('hello')
}
}
</script>

<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
</style>

App.vue

<template>
<div class="app">
<h1>{{msg}}</h1>
<School></School>
<Student></Student>
</div>
</template>

<script>
import Student from './components/Student'
import School from './components/School'

export default {
name:'App',
components:{School,Student},
data() {
return {
msg:'你好啊!',
}
},


}
</script>

<style scoped>
.app{
background-color: gray;
padding: 5px;
}
</style>

main.js

import Vue from 'vue'

import App from './App'
import VueRouter from 'vue-router'

// VueRouter引入到Vue类中
Vue.use(VueRouter)

Vue.config.productionTip = false

new Vue({
el:'#app',
render:h=>h(App),
beforeCreate () {
// this就是Vue实例对象vm ,vm上有$on,$emit,$off,直接用它就行
Vue.prototype.$bus = this // 安装全局事件总线
}
})

全局事件总线总结

  1. 一种组件间通信的方式,适用于任意组件间通信。
  2. 安装全局事件总线:
    main.js

new Vue({
el:'#app',
render:h=>h(App),
beforeCreate () {
// this就是Vue实例对象vm ,vm上有$on,$emit,$off,直接用它就行
Vue.prototype.$bus = this // 安装全局事件总线
}
})

  1. 使用事件总线:
  1. 接收数据:
    在School组件的生命周期钩子中添加事件到事件总线(​​$bus​​)上 回调留在留在School组件自身
  2. 最好在beforeDestroy钩子中,用​​$off​​去解绑当前组件所用到的事件

mounted () {
// 给$bus绑定个自定义事件hello,回调函数在School组件里
this.$bus.$on('hello',(data)=>{
console.log('我是School组件,我收到了数据:',data);

})
},
// 在销毁前解绑$bus
beforeDestroy () {
this.$bus.off('hello')
}

  1. Student组件提供数据:

<button @click="SendStudentName">把Student数据给School</button>

methods: {
SendStudentName(){
// 触发$bus身上的自定义事件hello,并传个数据过去
this.$bus.$emit('hello',666)
}
}


参考:
​​​尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通​​


举报

相关推荐

0 条评论