vue系列--比较全的vue组件间通信

Vue组件间通信

1.props和$emit是最常用的,用于父子组件

2. 引用ref

// 使用子组件的属性
this.$refs.child.xxx

3. 使用$children和$parent

父组件调用子组件
vue系列--比较全的vue组件间通信_第1张图片

this.$children[0].xxx = xxx

子组件调用父组件

this.$parent.xxx = xxx

4. 兄弟组件,通过共同祖辈组件搭桥


this.$parent.$on(eventName, handler);

this.$parent.$emit(eventName, data);

5. 根据第3和第4种方法可以得到启发,使用自己写一个emitter用于向上通知和向下广播

// 向父组件通知事件
Vue.prototype.$dispatch = function(eventName, data) {
  let parent = this.$parent;
  while (parent) {
      parent.$emit(eventName, data);
      parent = parent.$parent;
  }
}

// 向所有子组件通知事件
function broadcast() {
  if (this.$children && this.$children.length) {
      const args = Array.from(arguments);
      const eventName = args[0];
      const data = args.slice(1);
      this.$children.forEach(child => {
          child.$emit(eventName, ...data);
          broadcast.apply(child, args);
      })
  }
}

Vue.prototype.$broadcast = function() {
  broadcast.apply(this, Array.from(arguments));
}

6. 祖先和后代,可以使用provide和inject,官方例子不建议修改,最好传初始值后就不改变


// 祖先
provide() {
  return {
    form: this
  }
}

// 后代
inject: ['form']

7. 祖先和后代还可以使用$attrs和$listeners


  
  

8. 任意两个组件之间,可以使用事件总线eventBus或者Vuex(Vuex单独讲解)


// 使用Vue快速定义bus
Vue.prototype.bus = new Vue();

// 自定义bus
export default class Bus {
  constructor() {
    this.onCache = {};
    this.emitCache = {};
    this.paramCache = {};
  }

  $on(eventName, handler) {
    if (!this.onCache[eventName]) {
      this.onCache[eventName] = [];
    }
    this.onCache[eventName].push(handler);
    if (this.paramCache[eventName]) {
      handler(...this.paramCache[eventName])
    }
  }

  $emit(eventName, ...data) {
    if (this.onCache[eventName]) {
      this.onCache[eventName].forEach(fn => {
        fn(...data);
      });
    }
    this.paramCache[eventName] = data;
  }

  $remove(eventName, fn) {
    if (this.onCache[eventName]) {
      if (fn) {
        for(let i = 0, len = this.onCache[eventName].length; i < len; i++) {
          if (fn === this.onCache[eventName][i]) {
            this.onCache[eventName].splice(i, 1);
            break;
          }
        }
      } else {
        this.onCache[eventName] = undefined;
        this.paramCache[eventName] = undefined;
        this.$emitCache[eventName] = undefined;
      }
    }
  } 
}

Vue.prototype.$bus = new Bus();

使用上面的自定义总线的,在监听之后,在组件销毁之前记得remove掉


created() {
  this.$bus.$on('busEvent', this.onBusEventHandler);
}

beforeDestroy() {
    this.$bus.$remove('busEvent', this.onBusEventHandler);
}

github地址能查看emitter和eventbus的用法
vue系列--比较全的vue组件间通信_第2张图片

你可能感兴趣的:(vue系列--比较全的vue组件间通信)