Vue 3 组件通信指南

112 阅读2分钟

Vue 3 组件通信指南

Vue 3 提供了多种方法来实现组件之间的通信,包括父子组件通信、兄弟组件通信、爷孙组件通信以及任意组件通信。本指南将介绍这些通信方式,并提供示例代码来说明如何在 Vue 3 中实现它们。

1. 父子组件通信

父子组件通信是最常见的一种通信方式,父组件可以向子组件传递数据,子组件可以通过事件将数据发送回父组件。

Props

父组件通过 props 向子组件传递数据:

<template>
  <child-component :message="parentMessage" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent!'
    };
  }
}
</script>

子组件接收父组件传递的数据:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: ['message']
}
</script>
Events

子组件通过事件向父组件发送数据:

<template>
  <button @click="sendData">Send Data</button>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('childEvent', 'Data from child');
    }
  }
}
</script>

父组件监听子组件事件:

<template>
  <child-component @childEvent="handleChildEvent" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleChildEvent(data) {
      console.log('Received data from child:', data);
    }
  }
}
</script>

2. 兄弟组件通信

兄弟组件通信需要借助一个共同的父组件或者一个事件总线来进行数据传递。

使用共同的父组件

兄弟组件通过共同的父组件进行数据传递:

<template>
  <div>
    <first-sibling :message="sharedMessage" @update="updateMessage" />
    <second-sibling :message="sharedMessage" @update="updateMessage" />
  </div>
</template>

<script>
import FirstSibling from './FirstSibling.vue';
import SecondSibling from './SecondSibling.vue';

export default {
  components: {
    FirstSibling,
    SecondSibling
  },
  data() {
    return {
      sharedMessage: ''
    };
  },
  methods: {
    updateMessage(message) {
      this.sharedMessage = message;
    }
  }
}
</script>
使用事件总线

兄弟组件通过事件总线进行数据传递:

// EventBus.js
import { createApp } from 'vue';
export const EventBus = createApp({});
// FirstSibling.vue
<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
import { EventBus } from '../EventBus';

export default {
  methods: {
    sendMessage() {
      EventBus.emit('message', 'Data from first sibling');
    }
  }
}
</script>
// SecondSibling.vue
<template>
  <div>{{ message }}</div>
</template>

<script>
import { ref, onMounted } from 'vue';
import { EventBus } from '../EventBus';

export default {
  setup() {
    const message = ref('');

    onMounted(() => {
      EventBus.on('message', data => {
        message.value = data;
      });
    });

    return {
      message
    };
  }
}
</script>

3. 爷孙组件通信

爷孙组件通信通过在中间层的组件中传递数据来实现,也可以使用 provide 和 inject。

中间层组件

中间层组件负责传递数据给子组件:

<template>
  <middle-component :message="grandParentMessage" />
</template>

<script>
import MiddleComponent from './MiddleComponent.vue';

export default {
  components: {
    MiddleComponent
  },
  data() {
    return {
      grandParentMessage: 'Hello from grandparent!'
    };
  }
}
</script>
使用 provide 和 inject

爷孙组件之间可以通过 provide 和 inject 来传递数据:

// GrandParent.vue
<template>
  <div>
    <parent-component />
  </div>
</template>

<script>
import { provide } from 'vue';
import ParentComponent from './ParentComponent.vue';

export default {
  components: {
    ParentComponent
  },
  setup() {
    const grandParentMessage = 'Hello from grandparent!';
    provide('grandParentMessage', grandParentMessage);
  }
}
</script>
// ParentComponent.vue
<template>
  <child-component />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
}
</script>
// ChildComponent.vue
<template>
  <div>{{ grandParentMessage }}</div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    const grandParentMessage = inject('grandParentMessage');
    return {
      grandParentMessage
    };
  }
}
</script>