之前一篇博客,我们介绍了子组件向父组件通信的方法,可以参考博客:
深度理解Vue组件的子组件向父组件传递数据的通信方式,全面详细,看这一篇就够了,推荐收藏_czjl6886的博客-CSDN博客
今天,我们来讲一讲,任意组件之间的通信方法,主要有全局事件总线、消息订阅与发布、vuex和缓存,vuex和缓存在实际开发中不经常使用,因此就只讲前面2种方式。
目录
2.引入:import pubsub from 'pubsub-js'
方法一:全局事件总线
全局事件总线,是程序员们,在开发过程中,对现有东西和经验的总结与整合,不是一个新的API或其他新的东西。
第一步:安装全局事件总线:
在 main.js 文件中,添加代码:
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
// 安装全局事件总线
beforeCreate(){
Vue.prototype.$bus = this
}
}).$mount('#app')
即:第 9-11 行代码,含义是向 Vue 的原型上添加一个全局属性 $bus ,这个全局属性的名字是自定义的,可以命名为 zongxian、abc 等等,但是一般我们都是定义为 bus ,或者 $bus ,我这里定义为 $bus ,每个 vue 实例中,就会有这个 $bus 属性。
如下图:
因为 bus 有 计算机系统的总线 的含义,所以我们就常用这个来命名。
第二步:使用全局事件总线
案例: Brother1 组件与 Brother2 组件进行通信,点击 Brother2 组件的按钮,将 Brother2 组件的姓名传给 Brother1 组件
Brother1 组件接收Brother2 组件中的数据,则在Brother1 组件中给 $bus 绑定自定义事件,事件的回调函数在 Brother1 组件中定义。
Brother1 组件接收数据:
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
上述的这种形式是:在methods中定义一个demo函数,在挂载的过程中,将一个自定义事件XXX,与demo函数绑定,然后挂载完毕执行函数demo,即:组件一挂载完就去监听该事件。
事件名字和函数名字都可以随意命名。
<template>
<div class="outer">
<h2>我是Brother1组件</h2>
<h3>姓名:{{name1}}</h3>
<!-- <button>点我将Brother1的姓名传给Brother2</button> -->
</div>
</template>
<script>
export default {
name:'Brother1',
data(){
return{
name1:"小李"
}
},
methods: {
demo(data){
console.log('我是Brother1组件,我收到了Brother2组件的name:',data);
}
},
mounted() {
this.$bus.$on('helloName',this.demo)
},
}
</script>
<style scoped>
.outer{
width: 400px;
height: 400px;
background-color: lightblue;
margin-left: 30px;
margin-top: 50px;
float: left;
}
</style>
上述形式可以简写为下面:将定义回调函数,直接与自定义事件绑定在一起
注意:回调函数要写成箭头函数的形式
mounted() {
this.$bus.$on('xxxx',回调函数)
}
<template>
<div class="outer">
<h2>我是Brother1组件</h2>
<h3>姓名:{{name1}}</h3>
<!-- <button>点我将Brother1的姓名传给Brother2</button> -->
</div>
</template>
<script>
export default {
name:'Brother1',
data(){
return{
name1:"小李"
}
},
// methods: {
// demo(data){
// console.log('我是Brother1组件,我收到了Brother2组件的name:',data);
// }
// },
mounted() {
this.$bus.$on('helloName',(data) => {
console.log('我是Brother1组件,我收到了Brother2组件的name:',data);
})
},
}
</script>
<style scoped>
.outer{
width: 400px;
height: 400px;
background-color: lightblue;
margin-left: 30px;
margin-top: 50px;
float: left;
}
</style>
注意事项:最好在beforeDestroy钩子中,用$off解绑当前组件所用到的事件,避免同事写的代码中出现同名事件,导致代码bug
beforeDestroy() {
this.$bus.$off('helloName')
},
Brother2 组件提供数据:
Brother2 组件触发相应事件,将数据传给Brother1 组件
this.$bus.$emit('xxxx',数据)
<template>
<div class="outer">
<h2>我是Brother2组件</h2>
<h3>姓名:{{name2}}</h3>
<button @click="sendName">点我将Brother2的姓名传给Brother1</button>
</div>
</template>
<script>
export default {
name:'Brother2',
data(){
return{
name2:"小王"
}
},
methods: {
sendName(){
this.$bus.$emit('helloName',this.name2)
}
},
}
</script>
<style scoped>
.outer{
width: 400px;
height: 400px;
background-color: pink;
margin-left: 30px;
margin-top: 50px;
float: left;
}
</style>
最后实现的效果如下:
方法二:消息订阅与发布
案例:
Brother1 组件与 Brother2 组件进行通信,点击 Brother2 组件的按钮,将 Brother2 组件的姓名传给 Brother1 组件
使用步骤:
1.安装 pubsub:npm i pubsub-js
2.引入:import pubsub from 'pubsub-js'
在 Brother1 组件与 Brother2 组件中引入 pubsub
3.接收与发送数据
Brother1 组件接收数据,则在Brother1 组件中订阅消息,订阅的demo回调函数留在Brother1 组件里面,形式如下:
methods(){
demo(data){......}
}
......
mounted() {
this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}
<template>
<div class="outer">
<h2>我是Brother1组件</h2>
<h3>姓名:{{name1}}</h3>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'Brother1',
data(){
return{
name1:"小李"
}
},
methods: {
demo(msgName,data){
console.log('消息名字是:',msgName);
console.log('我是Brother1组件,我收到了Brother2组件的name:',data);
}
},
mounted() {
this.pid = pubsub.subscribe('helloName',this.demo)
},
}
</script>
<style scoped>
.outer{
width: 400px;
height: 400px;
background-color: lightblue;
margin-left: 30px;
margin-top: 50px;
float: left;
}
</style>
上述形式,可以简写为 下面形式:注意,回调函数要写成箭头函数的形式
mounted() {
this.pid = pubsub.subscribe('xxx',回调函数) //订阅消息
}
为避免出现错误 ,最好在 beforeDestroy 钩子中,用 PubSub.unsubscribe(pid)
去取消订阅
Brother2 组件提供数据:形式为如下:
注意下面的'xxx',名字一定要和接收数据的组件中,订阅的消息名一样
pubsub.publish('xxx',数据)
<template>
<div class="outer">
<h2>我是Brother2组件</h2>
<h3>姓名:{{name2}}</h3>
<button @click="sendName">点我将Brother2的姓名传给Brother1</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'Brother2',
data(){
return{
name2:"小王"
}
},
methods: {
sendName(){
pubsub.publish('helloName',this.name2) //发布消息
}
},
}
</script>
<style scoped>
.outer{
width: 400px;
height: 400px;
background-color: pink;
margin-left: 30px;
margin-top: 50px;
float: left;
}
</style>
最终实现的效果如下:
公共事件总线、消息订阅与发布的区别:
注意:非常重要!!!
订阅消息时,箭头函数的参数和公共事件总线的箭头函数参数不一样了,第一个是消息的名称,第二个是消息携带的数据
PS:如果对你有帮助的哈,建议一键三联!,如有疑问,欢迎在评论区留言噢!