Technology Sharing

A complete guide to Vue 3 component communication: from basics to advanced techniques

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

introduction

Vue 3 introduced the Composition API, which brought new flexibility and power to component communication.

Component Communication Basics

Definition and function of components

In front-end development, a component can be seen as an independent unit for building a user interface. It encapsulates specific functions and styles, can be reused, and can be developed and tested independently of other parts. The main role of a component is to improve the reusability, maintainability, and scalability of the code. By splitting the interface into multiple components, developers can more easily manage complex applications and can optimize each component, thereby improving overall development efficiency and application performance.

Component tree and parent-child component relationships

In front-end frameworks such as Vue.js, components can be nested to form a component tree. In this tree structure, each component can have subcomponents, and these subcomponents can have their own subcomponents, forming a hierarchical structure. This structure makes the relationship between components clear and easy to manage and maintain.

  • Parent-child component relationship: In the component tree, a component can create another component. In this case, the creator is called the parent component and the created component is called the child component. The parent component can pass data and methods to the child component, and the child component can send information to the parent component through events. This parent-child relationship is the basis of component communication.
  • Sibling component relationship:Multiple child components under the same parent component are sibling components. Sibling components cannot communicate directly, and the communication between them usually needs to be transferred through the parent component.
  • Ancestor and descendant component relationships: In the component tree, the parent of a parent component is the ancestor component, and the child of a child component is the descendant component. This relationship is especially important when dealing with deeply nested components.

The concepts of component tree and parent-child component relationship are crucial to understanding component communication. Mastering these basics can help developers design and implement communication mechanisms between components more effectively.

Parent-child component communication (Vue 3)

Passing data from parent to child (Props)

What are props
Props is a mechanism for passing data from a parent component to a child component. In Vue 3, usedefinePropsAPI is used to declare receiving props, which maintains the one-way flow of data and ensures the independence and reusability of components.

How to pass props in parent component
In the parent component's template, usev-bindor abbreviation:To bind data:

  1. <template>
  2. <ChildComponent :my-prop="parentData" />
  3. </template>

here,:my-propIndicates that this is a dynamically bound prop.parentDataIs the data defined in the parent component

How to receive props in child components
In the child component, usedefinePropsTo declare the received props:

  1. <script setup>
  2. import { defineProps } from 'vue';
  3. const props = defineProps({
  4. myProp: String
  5. });
  6. </script>

exist<script setup>In the syntax sugar,definePropsWill automatically expose props as responsive properties of the component

Child passes events to parent (Emit)

What is emit
Emit is a mechanism for child components to send messages to parent components. In Vue 3, usedefineEmitsAPI to declare events that can be emitted, and useemitFunction to trigger the event.

How to trigger events in child components
In the child component's method, use defineEmits To declare events that can be emitted, and use emit To trigger:

  1. <script setup>
  2. import { defineEmits } from 'vue';
  3. const emit = defineEmits(['my-event']);
  4. function triggerEvent() {
  5. emit('my-event', dataToPass);
  6. }
  7. </script>

defineEmitsUsed to declare events that a component can emit, andemitFunctions are used to trigger these events.

How to listen to child component events in parent component
In the parent component's template,usev-onor abbreviation@ To listen to events emitted by child components:

  1. <template>
  2. <ChildComponent @my-event="handleEvent" />
  3. //或者<ChildComponent v-on:my-event="handleEvent" />
  4. </template>

here,@my-eventIndicates that the monitoring subcomponent sendsmy-eventevent,handleEventIt is a method defined in the parent component. When the event is triggered, this method will be called.

Comprehensive Example

Assume there is a parent componentParentComponentand a subcomponentChildComponent, the parent component needs to pass data to the child component, and the child component needs to notify the parent component after a specific operation.

Parent ComponentParentComponent.vue

  1. <template>
  2. <ChildComponent :my-prop="parentData" @child-event="handleChildEvent" />
  3. </template>
  4. <script setup>
  5. import { ref } from 'vue';
  6. import ChildComponent from './ChildComponent.vue';
  7. const parentData = ref('initial data');
  8. const handleChildEvent = (data) => {
  9. console.log('Received data from child:', data);
  10. };
  11. </script>

SubassemblyChildComponent.vue

  1. <template>
  2. <button @click="sendDataToParent">Send Data to Parent</button>
  3. </template>
  4. <script setup>
  5. import { defineProps, defineEmits } from 'vue';
  6. const props = defineProps({
  7. myProp: String
  8. });
  9. const emit = defineEmits(['child-event']);
  10. function sendDataToParent() {
  11. emit('child-event', props.myProp);
  12. }
  13. </script>

In this example, the parent component passes:my-propPass data to child components and pass@child-eventListen for events emitted by child components.definePropsReceives the parent component'smyPropand use it in button click eventemitSend data to the parent component.

Using Pinia (state management library for Vue 3)

Pinia's advantages and features

Pinia is the official recommended state management library for Vue 3. It provides a component-based way to manage application state. Here are some of the main advantages and features of Pinia:

  • Component API: Pinia uses a component-based API, making the separation of state management and component logic more natural.
  • TypeScript support: Pinia has considered TypeScript support from the beginning, allowing for better type inference and editor support when developing with TypeScript.
  • Modularity: Pinia allows you to split the state into multiple stores, each store can manage its own state and logic independently.
  • Combination API compatible: Pinia is perfectly integrated with Vue 3's Composition API, making the separation of state management and component logic more natural.
  • Time Travel Debugging: Pinia provides time travel debugging capabilities, allowing developers to easily backtrack and inspect state changes.
How to set up and use Pinia

To start using Pinia, you first need to install Pinia:

npm install pinia

Or using Yarn:

yarn add pinia

Then, set up Pinia in your Vue app:

  1. import { createPinia } from 'pinia';
  2. const pinia = createPinia();
  3. app.use(pinia);

Create a store:

  1. import { defineStore } from 'pinia';
  2. export const useCounterStore = defineStore('counter', () => {
  3. const count = ref(0);
  4. function increment() {
  5. count.value++;
  6. }
  7. return { count, increment };
  8. });

Use the store in your component:

  1. <script setup>
  2. import { useCounterStore } from '@/stores/counter';
  3. const counterStore = useCounterStore();
  4. </script>
  5. <template>
  6. <div>
  7. <p>Count: {{ counterStore.count }}</p>
  8. <button @click="counterStore.increment">Increment</button>
  9. </div>
  10. </template>
Pinia integration with components

Pinia is very easy to integrate with components, mainly throughdefineStorefunction to create a store. In the component, you can directly use the state and methods in the store:

  1. <template>
  2. <div>
  3. <p>Count: {{ count }}</p>
  4. <button @click="increment">Increment</button>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { useCounterStore } from '@/stores/counter';
  9. const counterStore = useCounterStore();
  10. const { count, increment } = storeToRefs(counterStore);
  11. //如果这里不使用storeToRefs会丢失响应式特性
  12. </script>

In the above example, we access the template directlycountTo display the counter value, and call it in the button click eventincrementmethod to increase the counter value.

Vue 3's unique communication method

Provide/Inject

Basic usage of Provide/Inject
In Vue 3,provideandinjectIt is a way of communication between parent and child components, allowing an ancestor component to inject a dependency into all its descendant components, no matter how deep the component hierarchy is.

  • provide data: Ancestor component usesprovideFunctions provide data.
  • Injecting data: Descendant components useinjectFunction to inject data.

Where to use Provide/Inject
provideandinjectApplicable to the following scenarios:

  • When you wish to avoid multiple layerspropsWhen passing data.
  • When you want multiple components in the component tree to share data.

Sample Code

  1. // 祖先组件
  2. export default {
  3. setup() {
  4. const message = 'Hello from Ancestor!';
  5. provide('message', message);
  6. }
  7. }
  8. // 子孙组件
  9. export default {
  10. setup() {
  11. const message = inject('message');
  12. return { message };
  13. }
  14. }
Teleport

Teleport concept and purpose
TeleportIt is a new built-in component added in Vue 3, which allows you to "teleport" a part of the template inside a component to any other location in the DOM.

How to use Teleport for component communication
TeleportIt is not used for communication between components, but for controlling the rendering position of components.TeleportRenders parts of a component into the DOM of its parent component, thus enabling a special way of communication.

Sample Code

  1. <!-- 父组件 -->
  2. <template>
  3. <div>
  4. <Teleport to="body">
  5. <ChildComponent />
  6. </Teleport>
  7. </div>
  8. </template>
  9. <!-- 子组件 -->
  10. <template>
  11. <div>Some content</div>
  12. </template>
Composition API

Introduction to the Composition API
Vue 3 introduced the Composition API, which provides a new way to organize and reuse logic.setupFunctions allow developers to more flexibly control the responsive state and lifecycle of components.

Using ref and reactive for inter-component communication
refandreactiveIt is a tool in the Composition API for creating responsive data.

  • refUsed to create responsive references of basic data types.
  • reactiveUsed to create a responsive reference to an object type.

Using provide and inject in the Composition API
In the Composition API,provideandinjectallowablesetupUsed in functions to achieve cross-component communication.

Sample Code

  1. // 祖先组件
  2. import { provide } from 'vue';
  3. export default {
  4. setup() {
  5. const message = ref('Hello from Ancestor!');
  6. provide('message', message);
  7. }
  8. }
  9. // 子孙组件
  10. import { inject } from 'vue';
  11. export default {
  12. setup() {
  13. const message = inject('message');
  14. return { message };
  15. }
  16. }

Through these Vue 3-specific communication methods, developers can organize communication between components more flexibly and improve the maintainability and reusability of the code.

Summarize

Vue 3 introduces the Composition API, which brings new flexibility and powerful features to component communication. Component communication is the key to building complex user interfaces in front-end development. It involves data transfer and event triggering between parent-child components, sibling components, and ancestor and descendant components. Vue 3 provides a variety of communication methods, including traditional props and emit, as well as the newly added Provide/Inject, Teleport, and Composition APIs.

Related information recommended

Creation is not easy. If this article helps you, can you give it a thumbs up?