我们意识到之前是子组件向父组件传递数据。显然,这还不够。看了这篇博客,不管是哪两个组件传递和接收数据,都没有问题!全局事件总线的原理(适用于任何组件之间的通信):(看图就懂)主要是把事件放到x上,然后把事件的回调放到想要获取的组件上数据。谁要传数据,调用x就可以了,把相应的事件存起来,把数据存进去,相当于一个中间人(哎,不得不说,一出生就用上了)。当然,不是每个人都能完成这项任务。x需要满足两个条件:所有Components都可以看到x有on、on、on、off和$emit方法。我们命名为x$bus我们在main.js文件中定义它并在vm实例对象上创建它,因为vm实例对象只有两种创建全局事件总线的方式:1.constDemo=Vue.extend({})constd=newDemo()Vue.prototype.$bus=d(在Vue的创建之外定义)2.newVue({......beforeCreate(){Vue.prototype.$bus=this//安装全局事件总线,$bus是当前应用的vm},})newVue({render:h=>h(App),beforeCreate(){Vue.prototype.$bus=this//安装全局事件总线}}).$mount('#app')使用事件总线:接收数据:一个组件要接收数据,然后给它在一个组件$bus绑定一个自定义事件,回调事件的留在A组件本身的mounted(){//或者指向一个方法,在methods中定义//在全局事件总线bus中绑定一个hello事件,然后回调是一个箭头函数,用于在this.bus中接收数据并绑定一个hello事件,后续回调为箭头函数,用于在this.bus中接收数据并绑定一个hello事件,后续回调为箭头函数,用于接收数据this.bus.$on("hello",(value)=>{console.log("Igotthedata",value);});},providedata:methods:{sentMyName(){//触发hello在这个方法中对于这个事件,将数据传递给this.bus.bus.bus.emit('hello',this.myName)}},使用这个方法的好处是!我们不再需要在标签中绑定自定义事件,只需要在$bus中创建事件,在需要传递数据的地方调用即可!当然,还有一点需要注意。如果你不使用事件或绑定了事件的组件,你应该养成随时解绑的好习惯!不要占用空间,会导致空间浪费,造成卡顿。最好在beforeDestroy钩子中使用$off来解除绑定当前组件使用的事件。在绑定事件的组件(即需要数据的组件)中解绑beforeDestroy(){//解绑this.bus中名为hello的事件this.bus中名为hello的事件this.bus.off("hello");},记住!this.bus.off()必须写事件解绑定,否则off()必须写事件解绑定,否则off()必须写事件解绑定,否则busEvents中的所有事件都会解绑定!后果很严重!!!!消息订阅和发布(适用于任何组件之间的通信)原理:简单理解:需要数据的组件:订阅消息提供数据的组件:发布消息比第一种方式麻烦很多,需要安装pubsub,我们打开VScode的控制台,输入npmipubsub-js,在发送数据和接收数据的组件中安装。通过importpubsubfrom'pubsub-js'导入这个文件,然后开始使用它来接收数据:如果A组件要接收数据,那么在A组件中订阅消息,订阅回调停留在A组件本身的this.pubId=pubsub.subscribe('hello',(msgName,data)=>{console.log('IreceivedData',data);})这里有一点需要注意,就是回调函数的第一个参数,msgName,代表hello,是订阅消息的名称。这个一定要写,因为默认第一个参数是消息名,第二个参数是数据,所以不管怎样,第一个要占一个地方,可以给它起个名字,或者用下划线_来提供数据:方法:{sentMyName(){pubsub.publish('你好',this.myName)}}当然,如果订阅的消息不再使用,就必须删除,不能占用空间,但是删除订阅的消息不是用$off,而是publish.unsubscribe(this.pubId),其中this.pubId是每条消息创建的时候都会有一个id,就像一个定时器一样,我们删除它,删除它对应的id号beforeDestroy(){pubsub.unsubscribe(this.pubId)},我们用更多的来对比一下两者是前者,因为是在Vm中创建的,所以不需要导入包,最后分享一个方法:
