初学Vue
消息订阅与发布
概述
- 功能:
一种组件间通信的方式,实现任意组件间通信 - 使用步骤:
1、安装pubsub:npm i pubsub-js
2、引入:import pubsub from 'pubsub-js'
3、接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
methods(){
demo(data){
...}
}
...
mounted(){
this.pid = pubsub.subscribe('xxx',this.demo) // 订阅消息
}
4、提供数据:pubsub.publish('xxx',数据)
,xxx是订阅名
5、使用消息订阅与发布后,最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)
去取消订阅
6、需要注意的地方是消息订阅中this的指向,如果subscribe方法回调函数如果用普通函数标识,那么会因为引入了第三方的库,导致普通函数的this并不是指向组件实例对象,而是undefined
mounted(){
pubsub.subscribe('xxx',function(){
console.log(this) // undefined
......
}
) // 订阅消息
}
所以通常要么回调函数用箭头函数实现,要么通过this调用定义在methods中的方法。
举个例子
实现School.vue和Student.vue组件之间的通信
- App.vue
<template>
<div id="app">
<School></School>
<Student></Student>
</div>
</template>
<script>
import School from "./components/School.vue"
import Student from "./components/Student.vue"
export default {
name:"App",
components:{
School,Student},
}
</script>
<style>
#app{
background-color: grey;
}
</style>
- School.vue
<template>
<div class="school">
<h3>学校名称:{
{name}}</h3>
<h3>学校地址{
{address}}</h3>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:"School",
data(){
return {
name:"清华大学",
address:"北京"
}
},
methods:{
demo1(){
console.log("hello,我是School组件,我收到了来自Student组件的消息")
},
// 接收两个参数,第一个参数MsgName是订阅名,另一个接收到的才是数据(通常可以传对象)
demo2(MsgName,name){
console.log("我是School组件,我收到了来自Student组件的数据",MsgName,name);
}
},
mounted(){
this.pid1 = pubsub.subscribe('sayHello',this.demo1) // sayHello是订阅名,不是事件和函数
this.pid2 = pubsub.subscribe('recieveData',this.demo2) // subscribe方法有一个返回值id, 用于使用后取消订阅
},
beforeDestroy(){
// 当组件销毁前销毁
pubsub.unsubscribe(this.pid1) // 通过pid取消消息订阅
pubsub.unsubscribe(this.pid2)
}
}
</script>
<style>
.school{
background-color: lightgreen;
}
</style>
- Student.vue
<template>
<div class="student">
<h3>学生姓名:{
{name}}</h3>
<h3>学生年龄:{
{age}}</h3>
<button @click="sendMsgToSchool">点我给School组件发送消息</button>
<button @click="sendDataToSchool">点我把数据传给School组件</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:"Student",
data(){
return {
name:"张三",
age:21
}
},
methods:{
// 触发click事件后调用该方法
sendMsgToSchool(){
// 给指定订阅名发布消息
pubsub.publish('sayHello')
},
sendDataToSchool(name){
pubsub.publish('recieveData',this.name)
}
}
}
</script>
<style>
.student{
background-color: pink;
}
</style>