今天我们主要围绕全局事件总线,消息的订阅和发布来解说
一.全局事件总线
1.一种组件间通信的方式,适用于任意组件间通信。
2.安装全局事件总线:
new vue({
...
beforeCreate(){
Vue.prototype.$bus=this//安装全局事件总线,$bus就是当前应用的vm
},
})
3.使用事件总线:
(1).接收数据:A组件想接收B组件的数据,则在A组件中$bus绑定自定义事件,事件的回调留在A组件自身。
method(){
demo(data){......}
}
mounted(){
this.$bus.$on('xxx',this.demo)
}
(2).B组件提供数据:
this.$bus.$emit('xxx',数据)
4.最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
想必大家都觉得用文字去描述特别抽象
我们直接上代码描述:
//main.js
import Vue from 'vue'
import App from './app.vue'
// 关闭Vue的生产提示
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 安装全局事件总线,$bus就是当前应用的vm
beforeCreate(){
Vue.prototype.$bus=this
}
}).$mount('#app')
//app.vue
<template>
<div>
<h1>{{msg}}</h1>
<school/>
<student/>
</div>
</template>
<script>
import student from './components/student.vue'
import school from './components/school.vue'
export default({
name:'App',
components:{school,student},
data(){
return{
msg:'你好啊!'
}
},
})
</script>
#school.vue
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2 >学校名称:{{name}}</h2>
<h2 >学校地址:{{address}}</h2>
</div>
</template>
<script>
export default {
name:'mySchool',
data(){
return{
name:'尚硅谷atgui',
address:'上海',
}
},
mounted() {
this.$bus.$on('hello',(data)=>{
console.log('我是学校组件,收到了student的数据:',data)
})
},
beforeDestroy(){
// 给总线上的hello事件解绑
this.$bus.$off('hello')
}
}
</script>
<style scoped>
.demo{
background-color: red;
}
</style>
#student.vue
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2 >学生姓名:{{name}}</h2>
<h2>性别:{{sex}}</h2>
<button @click="sendStudentName">把学生名给school组件</button>
</div>
</template>
<script>
export default {
name:'myStudent',
data(){
return{
name:'张三',
sex:'male',
n:0
}
},
methods: {
sendStudentName(){
this.$bus.$emit('hello',this.name)
}
},
}
</script>
<style scoped>
.demo{
background-color: aqua;
}
</style>
如图所示:
二.消息的订阅和发布
1.一种组件间通信的方式,适用于任意组件间通信
2.使用步骤:
(1)安装pubsub:npm i pubsub-js
(2)引入:import pubsub from 'pubsub-js'
(3)接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身methods(){
//回调函数
demo(data){.....}
}
mounted(){
this.pid=pubsub.surscribe('xxx',this.demo)
}
(4)B组件提供数据:pubsub.publish('xxx',数据)
(5)最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)消除订阅
同样我们也附上代码 方便理解:
//main.js
import Vue from 'vue'
import App from './app.vue'
// 关闭Vue的生产提示
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
#app.vue
<template>
<div>
<h1>{{msg}}</h1>
<school/>
<student/>
</div>
</template>
<script>
import student from './components/student.vue'
import school from './components/school.vue'
export default({
name:'App',
components:{school,student},
data(){
return{
msg:'你好啊!'
}
},
})
</script>
#school.vue
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2 >学校名称:{{name}}</h2>
<h2 >学校地址:{{address}}</h2>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'mySchool',
data(){
return{
name:'尚硅谷atgui',
address:'上海',
}
},
methods: {
demo(msgName,data){
console.log('有人发布了hello消息,hello消息的回调执行:'+data)
}
},
mounted() {
this.pubId=pubsub.subscribe('hello',this.demo)
},
beforeDestroy(){
pubsub.unsubscribe(this.pubId)
}
}
</script>
<style scoped>
.demo{
background-color: red;
}
</style>
#student.vue
<template>
<!-- 组件的结构 -->
<div class="demo">
<h2 >学生姓名:{{name}}</h2>
<h2>性别:{{sex}}</h2>
<button @click="sendStudentName">把学生名给school组件</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'myStudent',
data(){
return{
name:'张三',
sex:'male',
n:0
}
},
methods: {
sendStudentName(){
pubsub.publish('hello',this.name)
}
},
}
</script>
<style scoped>
.demo{
background-color: aqua;
}
</style>