同样可以实现任意组件间的通讯的这么一个技术:
消息订阅与发布
- 1.订阅消息:消息名
- 2.发布消息:消息内容
比如App中有一个A组件中订阅了一个demo函数,回调函数是test
在App中的B中有一个C组件中发布一个消息和发布消息的信息(这个消息如果是与A组件的demo名字不相同的话C组件发布归发布,A组件接收不到数据;当C组件发布的消息与A组件的demo名相同,C一代发布,A组件由于订阅了demo消息所以test函数就会触发调用)
- 需要数据的人订阅消息
- 提供数据的人发布消息
原生的js没有这个功能,所以要借助第三方库,这里推荐pubsub-js
School.vue
<template>
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
</div>
</template>
<script>
export default{
name:'School',
components:{},
data() {
return {
name: 'bilibili',
address:'魔都'
}
},
}
</script>
<style>
</style>
Student.vue
<template>
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<button @click="">把学生名给School</button>
</div>
</template>
<script>
export default{
name:'Student',
components:{},
data() {
return {
name:'张三',
sex:'男'
}
},
methods: {
sendStudentName(){
}
},
}
</script>
<style>
</style>
- 这里School组件需要数据
- 这里Student组件要传输数据
安装pubsub-js
npm i pubsub-js
先从收数据的人开始(School.vue)
import pubsub from 'pubsub-js'
它(pubsub
)是一个对象,其中有一个API可以用来订阅
mounted() {
pubsub.subscribe('hello',function(){
console.log('有人发布了hello消息,hello消息的回调函数被执行了')
})
},
在Student.vue
里面发布消息:
import pubsub from 'pubsub-js'
sendStudentName(){
pubsub.publish('hello',666)
}
数据是以形参的形式传递回来的,那么:
mounted() {
pubsub.subscribe('hello',function(res){
console.log('有人发布了hello消息,hello消息的回调函数被执行了',res)
})
},
得到的结果是:
有人发布了hello消息,hello消息的回调函数被执行了 hello
但是你再加一个参数:
mounted() {
pubsub.subscribe('hello',function(msgName,data){
console.log('有人发布了hello消息,hello消息的回调函数被执行了',msgName,data)
})
},
有人发布了hello消息,hello消息的回调函数被执行了 hello 666
数据就来了
发布消息和订阅消息也跟全局事件总线一样,当订阅消息没用的时候取消订阅:
pubsub.subscribe这个库设计有点像定时器, 也就是说你每次订阅一次消息都有一个订阅的id
const pubId = pubsub.subscribe()
你要去取消要通过id
去取消,但是mounted
里面的id
从beforeDestroy
读不到所以可以:
this.pubId = pubsub.subscribe()
beforeDestroy() {
pubsub.unsubscribe(this.pubId)
},
pubsub.subscrib里面的this是什么?
this.pubId = pubsub.subscribe('hello',function(msgName,data){
console.log(this)
})
undefined
你引用的第三方库Vue不敢保证你的this,所以你可以写箭头函数:
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
console.log(this)
})
总结
1.一种组件间通讯的方式,适用于任意组件间通信
2.引入:import pubsub from 'pubsub-js'
3.接收数据:A组件想接收函数,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){
demo(data){....}
}
....
mounted(){
this.pid = pubsub.subscribe('xxx',this.demo)//订阅消息
}
...
beforeDestroy(){
pubsub.unsubscribe(pid)
}
4.提供数据:pubsub.publish('xxx',数据)
5.最好在beforeDestroy钩子中,用pubsub.unsubscribe(pid)
去取消订阅
消息预发布则个技术挺好的,但是在vue里面用的并不多,因为Vue里面有一个跟它功能一致的就是事件总线