There are many ways to communicate between components. The following are 6 common direct or indirect component value transmission methods:
1. Props (father to son)
advantage:
Easy to understand, conform to the principle of one-way data flow, and is conducive to code maintenance.
shortcoming:
- Data can only be passed from the parent component to the child component, and cannot be passed backwards. If multiple levels of pass are required, props need to be passed down layer by layer.
- When the application scales, excessive dependence on props may lead to increased coupling between components.
2. Custom events (son to parent)
advantage:
It realizes the transfer of data from child components to parent components, following the principle of responsive design.
shortcoming:
- Communication between adjacent components can only be realized, and communication between multi-level nested components is more complicated.
- If the interaction between components is complex, it may lead to the use of a large number of custom events, affecting the readability and maintainability of the code.
3. $refs and direct call method
advantage:
Very convenient when it is necessary to operate on subcomponents or obtain their internal state.
shortcoming:
- It violates the component's encapsulation principle, so that the parent component has too much understanding and dependence on the internal implementation details of the child component.
- Not applicable to inter-component communication across levels, non-parent-child relationships.
4. Vuex
advantage:
- Provides a centralized state management mechanism to facilitate the sharing and management of state of multiple components.
- Supports asynchronous operation, suitable for large projects, and can effectively reduce the coupling between components.
shortcoming:
- For small projects, introducing Vuex can be too complex, increasing the development and learning costs of the project.
- Additional store modules and actions/mutations/getters are required to increase the amount of code.
5. Event Bus (global event bus)
advantage:
Simplify communication between any component, especially suitable for messaging between components that do not have direct associations.
shortcoming:
- Global events are prone to naming conflicts, and event names need to be managed with caution.
- When the project is large, it is difficult to track the source and where the incident is going, making it more difficult to maintain.
- As the complexity of the project increases, excessive dependence on Event Bus will lead to the overall architecture being confusing and difficult to debug and maintain.
6. provide/inject
advantage:
Data can be conveniently provided to any descendant components in the ancestor components without passing props layer by layer.
shortcoming:
- The injected data is not responsive (unless it is injected with a method that computes properties or Vue instances).
- It is easy to cause implicit strong coupling between components, which is not conducive to component independence and reusability.
Detailed code examples
1. Props (father to son)
The parent component passes data to the child component:
Parent component code:
<template> <ChildComponent :parentValue="valueFromParent" /> </template> <script> import ChildComponent from './'; export default { data() { return { valueFromParent: 'This is the data of the parent component' }; }, components: { ChildComponent } }; </script>
Subcomponent code:
<template> <div>{{ parentValue }}</div> </template> <script> export default { props: { parentValue: String // Receive and display the values from the parent component } }; </script>
2. Custom events (son to parent)
The child component passes data to the parent component:
Subcomponent code:
<template> <button @click="emitValue">Click to pass data</button> </template> <script> export default { methods: { emitValue() { this.$emit('childEvent', 'This is the data passed by the child component'); } } }; </script>
Parent component code:
<template> <ChildComponent @childEvent="handleChildEmit" /> </template> <script> import ChildComponent from './'; export default { methods: { handleChildEmit(value) { ('Received data from subcomponents:', value); // Update parent component status and other operations } }, components: { ChildComponent } }; </script>
3. $refs and direct call method
In some cases, the child component instance can be obtained through ref and its methods can be called directly in the parent component.
Subcomponent code:
<template> <div ref="childRef">...</div> <button @click="sendData">Send data</button> </template> <script> export default { methods: { sendData() { this.$emit('dataSent', ); } } }; </script>
Parent component code:
<template> <ChildComponent ref="child" @dataSent="handleData" /> </template> <script> import ChildComponent from './'; export default { methods: { handleData(data) { ('Data received through the event:', data); }, callChildMethod() { // Use $refs to access the child component instance and call the method this.$(); } }, components: { ChildComponent } }; </script>
4. Vuex
Use the global state management tool Vuex to enable communication across multiple hierarchical components.
Create a store in Vuex:
// import Vue from 'vue'; import Vuex from 'vuex'; (Vuex); export default new ({ state: { sharedData: null }, mutations: { setSharedData(state, data) { = data; } }, actions: { updateSharedData({ commit }, newData) { commit('setSharedData', newData); } }, getters: { getSharedData(state) { return ; } } });
Used within the component:
// In any component<template> <button @click="updateData">Update shared data</button> <AnotherComponent /> </template> <script> import { mapActions, mapGetters } from 'vuex'; export default { computed: { ...mapGetters(['getSharedData']) }, methods: { ...mapActions(['updateSharedData']), updateData() { ({ some: 'new data' }); } } }; </script>
5. Event Bus (global event bus)
Create a global event bus to allow communication between any components.
// import Vue from 'vue'; export const EventBus = new Vue();
Components that send events:
<template> <button @click="sendMessage">Send a message</button> </template> <script> import { EventBus } from './eventBus'; export default { methods: { sendMessage() { EventBus.$emit('customEvent', { message: 'Hello from component A!' }); } } }; </script>
Components that receive events:
<script> import { EventBus } from './eventBus'; export default { created() { EventBus.$on('customEvent', (data) => { ('Received message:', ); }); }, beforeDestroy() { // Don't forget to unbind the event listener when component is destroyed to avoid memory leaks EventBus.$off('customEvent'); } }; </script>
6. provide/inject
Vue provides and inject APIs to implement the way ancestor components provide dependencies to descendant components (no intermediate pass required).
The ancestor component provides data:
<script> export default { provide() { return { ancestorData: }; }, data() { return { someData: 'Data from ancestors' }; } }; </script>
Descendant components inject data:
<script> export default { inject: ['ancestorData'], mounted() { ('Data obtained from ancestors:', ); } }; </script>
Each of the above methods has its applicable scenarios and advantages and disadvantages. Please choose the appropriate method according to the actual project needs.
This is the article about 6 methods of passing values between components in vue. This is the end of this article. For more related contents of passing values between components in vue, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!