Vue组件间通信方式

2018-10-08
Vue组件之间有以下八种通信方式

Props & $emit

这是最常见的父子组件通信方式, 父组件通过props向子组件传递参数, 子组件通过$emit向父组件触发事件.

<!-- 父组件 -->
<template id="parent">
  <child :valueA="xxx" @fun="func"></child>
</template>

<!-- 子组件 -->
<script>
export default {
  props: {
    valueA: String
  },
  methods: {
    func(value) {
      this.$emit('fun', value);
    }
  }
};
</script>

$attrs 与 $listeners

props与$emit只可以在直接的父子组件中通信, 而如果想在父子组件中跨层通信则可以考虑$attrs与$listeners.

<!-- 子组件C -->
<template id="componentC">
  <button :value="$attrs.messageC" @click="emitCData($attrs.messageC)"></button>
</template>

<script>
export default {
  methods: {
    emitCData(val) {
      this.$emit('getCData', val);
    }
  }
};
</script>
<!-- 子组件B -->
<template id="componentB">
  <button :value="messageB" @click="emitBData(messageB)"></button>
  <!-- v-bind="$attrs"可以让C直接获取到A中传递下来的props(除了B中声明的props), v-on="$listeners"可以让C直接在A中触发getCData -->
  <ComponentC v-bind="$attrs" v-on="$listeners"></ComponentC>
</template>

<script>
export default {
  props: ['messageB'],
  data() {
    return {
      messageB: this.messageB;
    };
  },
  methods: {
    emitBData(val) {
      this.$emit('getBData', val);
    }
  }
};
</script>
<!-- 父组件A -->
<template>
  <ComponentB :messageB="messageB" :messageC="messageC" @getBData="getBData" @getCData="getCData">
</template>

中央事件总线EventBus

对于非父子关系的组件通信还可以设置一个Vue对象作为中央事件总线EventBus, 通过触发/监听EventBus中的事件(bus.$emit, bus.$on)可以进行组件间的通信.

let bus = new Vue();
// 触发
bus.$emit('eventName', value);
// 监听
bus.$on('eventName', value => {
    ...
});

provide & inject

父子间还可以通过provide/inject的方式进行组件通信, 由父组件的provide提供变量, 只要在父组件的生命周期内, 子组件无论多深层都可以通过inject来调用provide的数据.

// 父组件
export default {
  provide: {
    val: 'abc'
  }
}
// 子组件
export default {
  inject: ['val']
}

v-model

v-model的本质是props和$emit的语法糖, 默认为通过:value和@input来实现数据的双向绑定.

export default {
    model: {
    prop: 'value',
    event: 'input'
  },
  props: ['value'],
  methods: {
    // 触发input事件
    action(val) {
      this.$emit('input', val);
    }
  }
}

$parent & $children

可以通过访问this.$parent和this.$children来访问组件的父组件以及子组件

节制地使用 $parent 和 $children - 它们的主要目的是作为访问组件的应急方法. 更推荐用 props 和 events 实现父子组件通信

broadcast & dispatch

这是在vue1.0中使用的方法, 在vue2.x中已被废弃

broadcast可以向特定的父组件触发事件, 而dispatch可以向特定的子组件触发事件

vuex

vuex作为vue官方推荐的状态管理工具, 可以处理项目中的公共数据, 通过getter和mutation方法在vuex的外部获取/修改vuex存储的数据, 具体可以参考vuex的官网https://vuex.vuejs.org/zh/.