前言
使用过vue的同学大多数都知道on的使用。我们仅仅知道使用,有时候是完全不够的。现在我就带领大家写一个简单类似于vue空实例的中间件。
非父子组件的通信
非父子组件的通信vue官网给出这样的解决方案。 有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:
var bus = new Vue()// 触发组件 A 中的事件bus.$emit('id-selected', 1)// 在组件 B 创建的钩子中监听事件bus.$on('id-selected', function (id) { // ...})复制代码
简单例子
下面是一个很简单的例子
//工具var myBus = (function() { var clienlist = {}, addlisten, trigger, remove; /** * 增加订阅者 * @key {String} 类型 * @fn {Function} 回掉函数 * */ addlisten = function(key, fn) { if(!clienlist[key]) { clienlist[key] = []; } clienlist[key].push(fn); }; /** * 发布消息 * */ trigger = function() { var key = [].shift.call(arguments), //取出消息类型 fns = clienlist[key]; //取出该类型的对应的消息集合 if(!fns || fns.length === 0) { return false; } for(var i = 0, fn; fn = fns[i++];) { fn.apply(this, arguments); } }; /** * 删除订阅 * @key {String} 类型 * @fn {Function} 回掉函数 * */ remove = function(key, fn) { var fns = clienlist[key]; //取出该类型的对应的消息集合 if(!fns) { //如果对应的key没有订阅直接返回 return false; } if(!fn) { //如果没有传入具体的回掉,则表示需要取消所有订阅 fns && (fns.length = 0); } else { for(var l = fns.length - 1; l >= 0; l--) { //遍历回掉函数列表 if(fn === fns[l]) { fns.splice(l, 1); //删除订阅者的回掉 } } } }; return { $on: addlisten, $emit: trigger, $off: remove }})();//组件一Vue.component('vv-count', { props: ["count"], template: '\ { {count}} \', methods: { handelClick() { console.log('vv-count总计:', this.count); if(vue_bus){ //触发发布--使用vue bus.$emit("vv_count", this.count,'这是使用vue的') }else{ //触发发布--使用自己的 myBus.$emit("vv_count", this.count,'这是自己写的') } } }});//组件二Vue.component('vv-count1', { props: ["count"], template: '\ { {count}} \', methods: { handelClick() { console.log('vv-count1总计:', this.count); if(vue_bus){ //触发发布 bus.$emit("vv_count", this.count) }else{ //触发发布 myBus.$emit("vv_count", this.count) } } }});var vue_bus=true;// true:使用vue的事件总线,false:使用自己的事件总线if(vue_bus){ //中间件 var bus = new Vue(); //使用vue的事件总线--订阅 bus.$on("vv_count", function() { console.log("使用bus发布的参数==", arguments); });}else{ //使用自己的事件总线--订阅 myBus.$on("vv_count", function() { console.log("使用myBus发布的参数==", arguments); });}new Vue({ el: "#app"});复制代码
上面代码可以使用vue_bus=true 或者false 相互切换进行看效果。如图所示:
如果想看更加详细的讲解请预览 or总结
vue中的发布订阅跟自己写的发布订阅原理是相同的,希望大家能够get到知识。
打赏通道--我觉得不会有打赏。