[vue] 全局事件总线 this.$bus.$emit this.$bus.$on ,可以实现任意组件间通信
全局事件总线原理分析前提:x是个组件,不属于任何一个组件要求:A组件想要收到别的组件给的信息在A组件里给x绑定个自定义事件demo,对应的回调函数就留在A中D组件想给A传点数据,就可以这样做:在D组件里,写点代码触发x身上的demo事件,并且传点数据过去(666),x身上的demo事件被触发了,demo事件的回调函数就得执行,而这个回调函数在A组件里面,那之前D组件传的数据666,就在A组件里面要
全局事件总线原理分析
前提:x是个组件,不属于任何一个组件
要求:A组件想要收到别的组件给的信息
在A组件里给x绑定个自定义事件demo
,对应的回调函数就留在A中
D组件想给A传点数据,就可以这样做:
在D组件里,写点代码触发x身上的demo事件,并且传点数据过去(666),
x身上的demo事件被触发了,demo事件的回调函数就得执行,而这个回调函数在A组件里面,那之前D组件传的数据666,就在A组件里面
要求:B组件想收到点别的组件传的数据,
在B组件里写点代码,给x组件绑定个事件test,回调函数留在B组件中
当D组件给B组件传数据时,
在D组件中写点代码,触发x组件身上的test事件,带个数据8过去,
那D组件身上的test事件就会被触发,那test事件所对应的回调就会被执行,而这个回调函数在B中,B就会接收到test事件携带的数据8
整个应用里,各种绑定事件,触发事件,都靠x组件,
以上就是事件总线的原理图
要求:
-
所有人都能看到x
-
x能调用
$on
,绑定自定义事件
x能调用$off
,解绑事件
x能调用$emit
,触发事件
1. 所有人都能看到x
所有组件都能看到x组件
直接把x加到vue的原型上就好了,因为VueComponent.prototype.__proto__ === Vue.prototype
,把x加到vue的原型上,VC的实例也能访问到,组件也能访问到
[vue] 一个重要的内置关系 VueComponent.prototype.proto === Vue.prototype
举例:
2. x能调用$on
,$off
,$emit
$on
,$off
,$emit
在Vue的Prototype上
x想使用Vue原型上的这三个方法,x要么是vm(vue实例对象),要么是vc(组件实例对象)
d就是vc,就可以调用到$on
,$off
,$emit
这样就简单实现了Student给School传递数据,兄弟组件可以通信了
一般来说,不叫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 // 安装全局事件总线
}
})
全局事件总线总结
-
一种组件间通信的方式,适用于任意组件间通信。
-
安装全局事件总线:
main.jsnew Vue({ el:'#app', render:h=>h(App), beforeCreate () { // this就是Vue实例对象vm ,vm上有$on,$emit,$off,直接用它就行 Vue.prototype.$bus = this // 安装全局事件总线 } })
-
使用事件总线:
-
接收数据:
在School组件的生命周期钩子中添加事件到事件总线($bus
)上 回调留在留在School组件自身 -
最好在beforeDestroy钩子中,用
$off
去解绑当前组件所用到的事件
mounted () { // 给$bus绑定个自定义事件hello,回调函数在School组件里 this.$bus.$on('hello',(data)=>{ console.log('我是School组件,我收到了数据:',data); }) }, // 在销毁前解绑$bus beforeDestroy () { this.$bus.off('hello') }
- Student组件提供数据:
<button @click="SendStudentName">把Student数据给School</button>
methods: { SendStudentName(){ // 触发$bus身上的自定义事件hello,并传个数据过去 this.$bus.$emit('hello',666) } }
-
更多推荐
所有评论(0)