当前位置 : 主页 > 编程语言 > java >

消息订阅和发布、基础知识和实战应用

来源:互联网 收集:自由互联 发布时间:2023-02-04
1、基础知识 类别引用说明:订阅报纸。用户作为订阅者订购报纸,邮局派送报纸。 1、一种组件间通信的方式,适用于span style=color:red任意组件间通信/span。 2、使用步骤: 安装pubsub:

1、基础知识

类别引用说明:订阅报纸。用户作为订阅者订购报纸,邮局派送报纸。

1、一种组件间通信的方式,适用于<span style="color:red">任意组件间通信</span>。

2、使用步骤:

  • 安装pubsub:npm i pubsub-js(安装不成功、使用管理员权限运行) 在这里插入图片描述

  • 引入: import pubsub from 'pubsub-js'(订阅和发布都要引入) 3.

  • 3、接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的<span style="color:red">回调留在A组件自身。</span>

    methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息 }

    4、提供数据:pubsub.publish('xxx',数据)(这里的传参传两个、第一个是订阅名、第二个是数据)

    5、最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去<span style="color:red">取消订阅。</span>

    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), })

    <hr>

    2.2 School.vue

    <template> <div class="school"> <h2>学校名称:{{name}}</h2> <h2>学校地址:{{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>

    <hr>

    2.3 Student.vue

    <template> <div class="student"> <h2>学生姓名:{{name}}</h2> <h2>学生性别:{{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>

    <hr>

    2.4 App.vue

    <template> <div class="app"> {{msg}} <School/> <Student/> </div> </template> <script> import Student from './components/Student' import School from './components/School' export default { name:'App', components:{School,Student}, data() { return { msg:'你好啊!', } } } </script> <style scoped> .app{ background-color: gray; padding: 5px; } </style>

    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>

    <hr>

    3.1.2 App.vue 订阅消息

    <template> <div id="root"> <div class="todo-container"> <div class="todo-wrap"> <TheHeader @addTodo="addTodo" /> <TheList :todos="todos" /> <TheFooter :todos="todos" @checkAllTodo="checkAllTodo" @clearAllTodo="clearAllTodo" /> </div> </div> </div> </template> <script> import TheHeader from "./components/TheHeader"; import TheList from "./components/TheList"; import TheFooter from "./components/TheFooter.vue"; import pubsub from "pubsub-js"; export default { name: "App", components: { TheHeader, TheList, TheFooter }, data() { return { msg: "你好啊!", studentName: "", //由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升) todos: JSON.parse(localStorage.getItem("todos")) || [], // todos: [ // { id: "001", title: "吃饭", done: true }, // { id: "002", title: "睡觉", done: false }, // { id: "003", title: "打豆豆", done: true }, // ], }; }, methods: { //添加一个todo addTodo(todoObj) { this.todos.unshift(todoObj); }, //勾选or取消勾选一个todo checkTodo(id) { this.todos.forEach((todo) => { if (todo.id === id) todo.done = !todo.done; }); }, //删除一个todo deleteTodo(_, id) { this.todos = this.todos.filter((todo) => todo.id !== id); }, //全选or取消全选 checkAllTodo(done) { this.todos.forEach((todo) => { todo.done = done; }); }, //清除所有已经完成的todo clearAllTodo() { this.todos = this.todos.filter((todo) => { return !todo.done; }); }, }, watch: { todos: { deep: true, handler(value) { localStorage.setItem("todos", JSON.stringify(value)); }, }, }, mounted() { this.$bus.$on("checkTodo", this.checkTodo); // this.$bus.$on('deleteTodo',this.checkTodo) //订阅消息、调用方法里边的函数、参数两个。第一个订阅消息名称、第二个是数据。也可以直接写成箭头函数 this.pubId = pubsub.subscribe("deleteTodo", this.deleteTodo); }, beforeDestroy() { this.$bus.$off("checkTodo"); // this.$bus.$off('deleteTodo') // 取消订阅 pubsub.unsubscribe(this.pubId); }, }; </script>

    <hr>

    4、测试结果说明

    在这里插入图片描述 在这里插入图片描述

    网友评论