消息订阅和发布、基础知识和实战应用
1、基础知识
类别引用说明:订阅报纸。用户作为订阅者订购报纸,邮局派送报纸。
1、一种组件间通信的方式,适用于任意组件间通信。
2、使用步骤:
-
安装pubsub:
npm i pubsub-js
(安装不成功、使用管理员权限运行) -
引入:
import pubsub from 'pubsub-js'
(订阅和发布都要引入)
3、接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。
methods(){
demo(data){......}
}
......
mounted() {
this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
}
4、提供数据:pubsub.publish('xxx',数据)
(这里的传参传两个、第一个是订阅名、第二个是数据)
5、最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)
去取消订阅。
2、代码实例
实现的效果:student组件中的信息发送到School组件中。student作为信息的发布者,School组件订阅信息。
2.1 main.js
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
//创建vm
new Vue({
el:'#app',
render: h => h(App),
})
2.2 School.vue
<template>
<div class="school">
<h2 id="h0">学校名称:{{name}}</h2>
<h2 id="h1">学校地址:{{address}}</h2>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'School',
data() {
return {
name:'尚硅谷',
address:'北京',
}
},
mounted() {
// console.log('School',this)
/* this.$bus.$on('hello',(data)=>{
console.log('我是School组件,收到了数据',data)
}) */
this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
console.log(this)
// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
})
},
beforeDestroy() {
// this.$bus.$off('hello')
pubsub.unsubscribe(this.pubId)
},
}
</script>
<style scoped>
.school{
background-color: skyblue;
padding: 5px;
}
</style>
2.3 Student.vue
<template>
<div class="student">
<h2 id="h2">学生姓名:{{name}}</h2>
<h2 id="h3">学生性别:{{sex}}</h2>
<button @click="sendStudentName">把学生名给School组件</button>
</div>
</template>
<script>
import pubsub from 'pubsub-js'
export default {
name:'Student',
data() {
return {
name:'张三',
sex:'男',
}
},
mounted() {
// console.log('Student',this.x)
},
methods: {
sendStudentName(){
// this.$bus.$emit('hello',this.name)
pubsub.publish('hello',666)
}
},
}
</script>
<style lang="less" scoped>
.student{
background-color: pink;
padding: 5px;
margin-top: 30px;
}
</style>
2.4 App.vue
3、全局事件总线通信改为消息的订阅和发布
3.1 核心部分代码
这里只修改一处、删除列表项的数据方式改为消息订阅和发布的形式
3.1.1 TheItem.vue(样式省略)、发布消息
消息发布、将要删除的id传递给App.vue
- <template> <li> <label> <input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)" /> <span>{{ todo.title }}</span> </label> <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button> </li> </template> <script> import pubsub from 'pubsub-js' export default { name: "MyItem", //声明接收todo、checkTodo、deleteTodo props: ["todo"], methods: { //勾选or取消勾选 handleCheck(id) { //通知App组件将对应的todo对象的done值取反 // this.checkTodo(id); this.$bus.$emit('checkTodo',id) }, //删除 handleDelete(id) { if (confirm("确定删除吗?")) { //通知App组件将对应的todo对象删除 // this.deleteTodo(id); // this.$bus.$emit('deleteTodo',id) // 消息发布 pubsub.publish('deleteTodo',id) } }, }, }; </script>
3.1.2 App.vue 订阅消息
4、测试结果说明