vue学习(40)全局事件总线

全局事件总线.png
思路
  • 首先可以让所有组件访问到
    尝试1:是不是可以往window身上放一个x?widnow.x=123;虽然其他组件的确可以访问到,但在使用框架时很少去往window身上放东西,这的确不太好。放弃。
    尝试2:所有的组件都能看的见,那就是VueComponent的实例对象都能看的见,那么我们可以往VueComponent构造函数的原型对象上添加x,VueComponent.prototype.x=123;但是需要注意的是,我们并不能直接拿到VueComponent这个构造函数,还有最重要的一点,通过源码得知,其实每次组件创建都是通过一个新的VueComponent构造函数,那么他们的原型对象也不是一个,所以此路不通。
    尝试3:除了我们可以往VueComponent的原型对象上放,还可以往唯一的Vue构造函数的原型对象上放。
Vue.prototype.x=123;
  • 实现让x有图中的方法
    尝试1:很明显$on这些方法组件实例的身上就有,那么我们可以让x是一个组件的实例,换个方法拿VueComponent构造函数
const Demo = Vue.extend({});
const demo = new Demo();
Vue.prototype.x = demo;

尝试2:$on这些方法组件实例身上有的根本原因是在于这些方法在Vue构造函数的原型对象上面。所以如果x的值是Vue的实例对象也是可以的。在main.js中刚好有new这个实例对象,所以我们尝试写一下

const vm = new Vue({
  render: h => h(App),
}).$mount('#app');
Vue.prototype.x = demo;

执行代码发现报错,因为去定义x的时候,app已经挂载完成,子组件在mounted中给x绑定事件,就已经晚了。
尝试3:使用钩子

new Vue({
  render: h => h(App),
  beforeCreate(){
    //this本来就是这个vue实例,况且这里写vm也不行,妙
    Vue.prototype.x = this;
  }
}).$mount('#app');

备注:x一般叫$bus,因为bus刚好有总线的含义。

知识点
  1. 一种组件间的通信方式,适用于任意组件间通信。
  2. 安装全局事件总线
new Vue({
  ....
  Vue.prototype.$bus = this;
  .....
})
  1. 使用事件总线
    1. 如果A组件想接受数据,那么就给$bus定义一个自定义事件,并把回调写在A中。
    {
    ....
      mounted(){
        this.$bus.$on('peiqi',getData)
      }
      methods:{
        getData(data){.....}
      }
    ....
    }
    
    1. 提供数据this.$bus.emit('peiqi',666)
  2. 最好在beforeDestroy钩子中,用$off解绑当前组件所用到的事件。

你可能感兴趣的:(vue学习(40)全局事件总线)