前提:x是个组件,不属于任何一个组件
在A组件里给x绑定个自定义事件demo
,对应的回调函数就留在A中
D组件想给A传点数据,就可以这样做:
在D组件里,写点代码触发x身上的demo事件,并且传点数据过去(666),
x身上的demo事件被触发了,demo事件的回调函数就得执行,而这个回调函数在A组件里面,那之前D组件传的数据666,就在A组件里面
在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
,触发事件
所有组件都能看到x组件
直接把x加到vue的原型上就好了,因为VueComponent.prototype.__proto__ === Vue.prototype
,把x加到vue的原型上,VC的实例也能访问到,组件也能访问到
[vue] 一个重要的内置关系 VueComponent.prototype.proto === Vue.prototype
举例:
$on
,$off
,$emit
$on
,$off
,$emit
在Vue的Prototype上
x想使用Vue原型上的这三个方法,x要么是vm(vue实例对象),要么是vc(组件实例对象)
这样就简单实现了Student给School传递数据,兄弟组件可以通信了
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.js
new 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')
}
<button @click="SendStudentName">把Student数据给Schoolbutton>
methods: {
SendStudentName(){
// 触发$bus身上的自定义事件hello,并传个数据过去
this.$bus.$emit('hello',666)
}
}
参考:
尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通