Vue2 消息订阅与发布
1.pubsub-js 第三方库实现
实现任何框架的消息订阅发布
npm i pubsub-js
<template><div class="student"><h2>展示学生的名称:{{ name }}</h2><h2>展示学生的性别:{{ sex }}</h2></div>
</template><script>
import pubsub from "pubsub-js";export default {name: "MyStudentt",data() {//这里存放数据return {name: "我是一个人",sex: 12,};},mounted() {// console.log(this.$refs.school1.__proto__===this.$refs.school2.__proto__);//true// this.$bus.$on("show", (data)=>{// console.log('事件总线收到了数据',data); 两个都生效// this.name = data;// });// this.$bus.$on("show", (data)=>{// console.log('事件总线收到了数据1',data);// this.sex = data;// });//订阅一个消息 show 是一个主题const pubId = pubsub.subscribe("show", (msg, data) => {//消费者console.log("有人发布了消息,show消息回调成功", data);this.name = data;});this.pubId = pubId;// pubsub.subscribe('show',(msg,data)=>{//消费者// console.log('有人发布了消息,show消息回调成功',data);// this.sex = data;// })},beforeDestroy() {// this.$bus.$off("show");pubsub.unsubscribe(this.pubId);},
};
</script><style scoped>
.student {background-color: green;padding: 5px;margin-top: 30px;
}
</style>
<template><div class="school"><h2 >展示学校的名称:{{name}}</h2><h2>展示学校的地址:{{ address }}</h2><button @click="show">传入事件总线数据</button></div>
</template><script>import pubsub from 'pubsub-js';export default {name: "MySchool",data() {//这里存放数据return {name: "辽工",address: "锦州",};},methods:{show(){// this.$bus.$emit('show',this.name);pubsub.publish('show',this.name);}}};
</script>
<style scoped>.school{background-color: red;padding: 5px;margin-top: 30px;}</style>
<template><div class="app"><h1>{{ msg }}</h1><Student ref="student"/><MySchool ref="school"/></div>
</template><script>
//引入School组件 随便起名字
import Student from "./components/Student.vue";
import MySchool from "./components/School.vue"; export default {name: "App",components: {Student,MySchool,},data() {return {msg: "你好啊!",};},mounted(){}
};
</script><style scoped>
.app {background-color: gray;padding: 5px;
}
</style>
2.$nextTick
<template><divid="container"@mouseover="handleMouseOver"@mouseleave="handleMouseLeave"><div id="d"><input type="checkbox" v-model="todo.done" /><span @click="info" v-show="!todo.showUpdate">{{ todo.title }}</span><!-- v-inputfocus="todo.showUpdate" --><inputtype="text"ref="updateInput"v-model="updateTitle"@keyup.enter="submitUpdate"@blur="cancelUpdate"v-show="todo.showUpdate"/></div><div><button class="btn update" v-show="showDelete" @click="updateTodo">修改</button><button class="btn" v-show="showDelete" @click="deleteTodo">删除</button></div></div>
</template><script>
import pubsub from "pubsub-js";export default {name: "TodoItem",data() {return {todo: this.todoObj,updateTitle: "",showDelete: false,};},methods: {//todo.hasOwnProperty这个属性是否有api removeFocus() {// this.$refs.updateInput.blur();},info() {console.log(this.todo);},handleMouseOver() {this.showDelete = true;},handleMouseLeave() {this.showDelete = false;},deleteTodo() {// let a = this.$bus.$emit('removeTodo',this.todoObj.id)// console.log(a===this.$bus);//a === vmif (confirm("你确定要删除吗?")) {pubsub.publish("removeTodo", this.todoObj.id);}},updateTodo() {if (this.todo.showUpdate) {this.todo.showUpdate = false;} else {this.updateTitle = this.todo.title;// this.$bus.$emit("updateTodoInputShow", this.todoObj.id, true);this.todo.showUpdate = true;//vue 提供api 在下次dom节点更新完毕后执行的回调this.$nextTick(function(){this.$refs.updateInput.focus();// console.log(this.$refs.updateInput);});}//vue 是等方法结束以后才回去解析模板, input框 focus 在display状态是不会聚焦的},submitUpdate() {if (confirm("你确定要保存吗?")) {if(this.updateTitle.trim()===''){alert('输入不能为空')return;}this.$bus.$emit("updateTodo", this.todo.id, this.updateTitle);}this.todo.showUpdate = false;},cancelUpdate() {this.todo.showUpdate = false;},},props: {todoObj: {//传入的若是引用对象 则里面修改了,外面同样生效type: Object,required: true,},},directives: {// inputfocus(e,v){// if (v) {// e.focus();// }// }// inputfocus: {// inserted(element, value) {// if (value) {// element.focus();// }// },// update(element, value) {// if (value) {// element.focus();// }// },// },},
};
</script><style scoped>
#container:hover {background-color: #a09a9a;
}#container {display: flex;justify-content: space-between; /* 水平居左 */align-items: center; /* 垂直居中 */width: 500px;height: 30px;border: 0.1px solid #ccc;border-radius: 2px;padding-left: 10px;padding-top: 5px;padding-bottom: 5px;
}#container * {padding: 5px;
}.btn {width: 50px;height: 28px;color: white;background-color: #eb1212;border: 1px solid #ccc;border-radius: 5px;padding: 5px;margin-right: 15px;cursor: pointer; /* 鼠标悬停时显示手型光标 */transition: background-color 0.3s ease; /* 平滑过渡 */
}
.btn:hover {background-color: #d10d0d; /* 鼠标悬停时颜色变化 */
}.btn:active {background-color: #a00; /* 按下时颜色变化 */transform: translateY(2px); /* 按下时按钮下移效果 */
}.update {background-color: #1233eb;margin-right: 5px;
}
.update:hover {background-color: #4e70dc; /* 鼠标悬停时颜色变化 */
}
.update:active {background-color: rgb(71, 0, 170); /* 按下时颜色变化 */transform: translateY(2px); /* 按下时按钮下移效果 */
}
</style>