Vue组件间通信方式都有哪些?

Vue组件间通信方式都有哪些?
最新回答
看不见的坚强

2026-10-25 20:22:26

Vue组件间通信方式主要包括以下几种:

一、父子组件通信
  • Props传递

    适用场景:父组件向子组件传递数据。

    实现方式:子组件通过props定义接收的参数,父组件在子组件标签中通过属性传递数据。

    示例:

    <!-- 子组件 --><script>export default { props: { name: String, age: { type: Number, default: 18, required: true } }}</script><!-- 父组件 --><Children name="jack" :age="18" />
  • $emit触发自定义事件

    适用场景:子组件向父组件传递数据。

    实现方式:子组件通过$emit触发自定义事件并传递数据,父组件通过@事件名监听。

    示例:

    <!-- 子组件 --><script>export default { methods: { sendData() { this.$emit('add', { id: 1, name: 'good' }); } }}</script><!-- 父组件 --><Children @add="handleAdd($event)" />
  • ref获取子组件实例

    适用场景:父组件直接访问子组件的数据或方法。

    实现方式:父组件通过ref标记子组件,通过this.$refs.ref名访问子组件实例。

    示例:

    <!-- 父组件 --><Children ref="child" /><script>export default { mounted() { console.log(this.$refs.child.data); // 访问子组件数据 }}</script>
二、兄弟组件通信
  • EventBus(事件总线)

    适用场景:兄弟组件间传递数据。

    实现方式:创建一个中央事件总线(如Vue实例),通过$emit触发事件,$on监听事件。

    示例:

    // Bus.jsimport Vue from 'vue';export const Bus = new Vue();<!-- 组件A --><script>import { Bus } from './Bus.js';export default { methods: { sendMsg() { Bus.$emit('msg-event', 'Hello from A'); } }}</script><!-- 组件B --><script>import { Bus } from './Bus.js';export default { mounted() { Bus.$on('msg-event', (msg) => { console.log(msg); // 输出: Hello from A }); }}</script>
  • $parent或$root

    适用场景:通过共同父组件或根组件搭建通信桥梁。

    实现方式:兄弟组件通过this.$parent或this.$root访问同一父组件的方法或数据。

    示例:

    <!-- 兄弟组件A --><script>export default { methods: { sendToParent() { this.$parent.sharedData = 'Data from A'; } }}</script><!-- 兄弟组件B --><script>export default { mounted() { console.log(this.$parent.sharedData); // 输出: Data from A }}</script>
三、跨层级组件通信
  • $attrs与$listeners

    适用场景:祖先组件向深层后代组件传递数据或事件。

    实现方式:

    $attrs:包含父组件传递的未被props接收的属性(class和style除外)。

    $listeners:包含父组件传递的未被监听的事件。

    通过v-bind="$attrs"和v-on="$listeners"向下传递。

    示例:

    <!-- 祖先组件 --><Child :msg="msg" @custom-event="handleEvent" /><!-- 中间组件(无props声明) --><template> <Grandchild v-bind="$attrs" v-on="$listeners" /></template><!-- 后代组件 --><script>export default { mounted() { console.log(this.msg); // 输出: 祖先传递的msg this.$emit('custom-event', 'Data from Grandchild'); }}</script>
  • Provide与Inject

    适用场景:祖先组件向后代组件传递数据(无需逐层传递)。

    实现方式:祖先组件通过provide提供数据,后代组件通过inject注入数据。

    示例:

    <!-- 祖先组件 --><script>export default { provide() { return { sharedData: 'Data from Ancestor' }; }}</script><!-- 后代组件 --><script>export default { inject: ['sharedData'], mounted() { console.log(this.sharedData); // 输出: Data from Ancestor }}</script>
四、复杂场景通信
  • Vuex

    适用场景:多组件共享状态或复杂数据流管理。

    核心概念:

    State:存储共享数据。

    Getters:计算派生状态。

    Mutations:同步修改状态的方法。

    Actions:异步操作或批量提交mutations。

    示例:

    // store.jsexport default new Vuex.Store({ state: { count: 0 }, mutations: { increment(state) { state.count++; } }, actions: { asyncIncrement({ commit }) { setTimeout(() => commit('increment'), 1000); } }});<!-- 组件中使用 --><script>export default { computed: { count() { return this.$store.state.count; } }, methods: { increment() { this.$store.commit('increment'); }, asyncIncrement() { this.$store.dispatch('asyncIncrement'); } }}</script>
总结
  • 父子组件:优先使用props和$emit,简单场景可用ref。
  • 兄弟组件:推荐EventBus,次选$parent或$root。
  • 跨层级组件:选择$attrs/$listeners(批量传递)或Provide/Inject(直接注入)。
  • 复杂场景:使用Vuex管理全局状态。

根据组件关系和场景复杂度选择合适的方式,避免过度设计。