What are some strategies for establishing communication between sibling components in Vue?

Currently, my Vue app has a structure that includes a "blackout" component for displaying modals and a router-view for various sub-menus. These components are siblings at the same level.


<blackout v-if="this.popup.currentPopup"></blackout>
     ....
<router-view class="folder">
  ...child-component fetching data with a GET request
</router-view>

Within the dynamically loaded component in "blackout" (using the :is directive), there is a save button used to send data via a POST method. After clicking this save button, I need to refresh the data in the child component of the "router-view". How can I notify the sibling component that the modal component has made a post request and was closed?

After conducting some research, I came across a few potential solutions: using an event bus (considered an antipattern), watching the store state (storing the modal's state in Pinia), or communicating through this.$root (only available in Vue 2).

Answer №1

There are multiple methods you can explore to achieve your desired outcome:

  1. Using this.$root is not recommended as it goes against Vue principles and can make component communication confusing and hard to debug.
  2. The event bus pattern is another option, although it is considered controversial. Keep in mind that Vue 3 does not natively support this, so you may need to utilize a third-party library or create your own event emitter.
  3. A store like Pinia is often seen as a more efficient solution. It offers easier debugging and testing capabilities.

An alternative approach is to communicate through the parent component using props and emits:

// Parent.vue
// template
<Foo @success="isRequestSuccessful = true" />
<Bar :isRequestSuccesfull="isRequestSuccessful" />

// script
const isRequestSuccessful = ref(false)

Answer №2

Effective communication between components is crucial in frontend frameworks such as Vue.js.

Data can be transmitted from one component to another at the same level by utilizing tools like Event bus and state management systems (particularly popular is Vuex).

export default {
    name: "DemoComponent"
    methods: {
        sendMessage() {
            this.$root.$emit("message from Demo component", argument1, argument2)
        }
    }
}

export default {
    name: "TestComponent"
    methods: {
        this.$root.$on("Message from Demo", (argument1, argument2) => {
            console.log("Arg 1" + argument1);
            console.log("Arg 1" + argument2);
        }
    }
}

In large-scale applications, it is recommended to avoid using Event Bus and opt for Vuex instead. With Vue 3, methods like $on and $emit have been deprecated, potentially leading to console errors.

For further information, refer to articles located here and here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can the printing of content be adjusted when the browser zoom function is activated?

Is there a way to prevent the content from zooming when printing while the browser is zoomed in? The goal is for the printing (using iframe) to remain unchanged even if the browser is zoomed. I attempted: document.body.style.transformOrigin = 'top le ...

Finding distinct outcomes from an already screened roster using AngularJS

I have an array containing objects structured like this: { "date":"11/11/2014", "time":"17.20.37", "car":"396", "driver":"Jenny", "from":"Old Office", "destination":"Log WH", "pax":"3","comment":"", "commenttime":"", "arrival":"17.20.48", "inserted":true, ...

"Implement a smooth scrolling animation on the page to automatically move a div element upward and lock

I am attempting to create a unique animation for a header div that involves moving it to the top of the screen when the user scrolls down. Once the header div reaches the top, I want it to stay fixed in that position. As the header div moves upwards, it wi ...

Using Element UI to assign an id to a table column that includes a checkbox

Is there a way to assign an ID to el-table-column with the selection type? I attempted to use a slot for this purpose, but it caused the checkbox not to render. Below is the code snippet: <el-table-column> <template slot-scope="scope" v-if=" ...

Uncertainty about the integration of a JavaScript file into a PHP file

Having two PHP files where one is executed through a URL and makes AJAX calls to the second PHP file can present challenges. Sometimes, the AJAX results return HTML content with JavaScript events that do not work as expected. To solve this issue, I have in ...

What steps can I take to ensure my Vue website is tested on various devices and views before it goes live online?

My current project involves developing a website that utilizes Vue-js for the front-end, and Node + MySQL for the back-end. During development mode, when I connect to the internet and run npm run serve, I come across these lines in my command-line: https: ...

What is the process for making a referenced variable null?

My scenario is as follows: When a user clicks on a button in Phaser.io, I create a new Phaser.sprite and store it in a local variable called newSquare. This new sprite is then added to an array called Squares. At a later point, I call a function to destr ...

How to efficiently pass dynamic props in Next.js persisting layoutuciary

When setting up a persistence layout, I utilize the getLayout function on each page as shown below: import { Layout } from 'hoc'; const Page = () => { return ( <div>hello</div> ); }; Page.getLayout = function getLayout(pa ...

Tips for invoking a specific function based on a value within a v-on callback

Here's my code snippet: <form @submit.prevent="buttonName === 'Create' ? createCountries : updateCountries"> ----- ---- </form> methods :{ createCountries(){ ---- }, updateCountries ...

Is it possible to create a cross-sectional view of a lens using the HTML5 canvas element?

I am interested in creating a visual representation of the cross section of a lens element. Typically, these elements consist of one or two circular surfaces (front and back) with a rim of arbitrary shape. My goal is to simply connect the front and back su ...

What makes this effective in JavaScript?

While working on a project, I encountered the task of comparing coordinates in two arrays at the same index to see if they are identical. There are various methods to achieve this, but one particular approach piqued my interest. Why does it yield the expec ...

What is the best way to access the EXIF data of an image (JPG, JPEG, PNG) using node.js?

In my quest to access the EXIF data of an image in order to extract GPS information such as Latitude and Longitude, I have experimented with approximately 4-5 EXIF packages available on npm/node, including exif, exif-parser, node-exif, exifr, exif-js, and ...

Is it possible to devise a universal click handler in TypeScript that will consistently execute after all other click handlers?

In my ReactJS based application written in TypeScript, we have implemented various click handlers. Different teams contribute to the application and can add their own handlers as well. The challenge we face is ensuring that a specific global click handler ...

What's the reason behind ng-click only functioning with a function and not an assignment within this specific directive?

I am currently working on creating a dynamic table using an array of objects that can be sorted by clicking the headers. I have a specific question regarding how the sorting feature is implemented. let myDirectiveTemplate = ` <table class="directiveTab ...

Display a webpage containing error messages and user input that can be sent back to the AJAX request

My form collects user information such as name, surname, etc. Here is an example of one input field: <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" id="name" name="name" value= ...

Position the caret after adding a new element in a content-editable div

I have a contenteditable div that contains various elements. My goal is to automatically create a new paragraph tag right after the element where the cursor is positioned when the user presses the enter key. Currently, I am able to insert the paragraph tag ...

Discovering the means by which current route meta fields can be accessed in a typical JavaScript module for VueJs

I'm currently working on an application with the following route setup: const router = new Router({ mode: 'history', scrollBehavior: () => ({ y: 0 }), routes: [ { path: '/', component: HomePage, meta: { pageType: &apos ...

Tips for achieving the Bootstrap 5 Modal Fade Out effect without using jQuery or any additional plugins apart from Bootstrap

I'm facing some challenges in achieving the fade out effect in Bootstrap 5 modals. I am aiming for something similar to the "Fade In & Scale" effect demonstrated here: https://tympanus.net/Development/ModalWindowEffects/ It is crucial for me to accom ...

Utilizing requirejs for handling asynchronous callback functions with ajax

If I need to take advantage of the jQuery AJAX API features and customize settings for each ajax call made by my application, it can be done like this: For example, imagine a page that showcases employee information in a table using ajax calls to an API. ...

An easy way to create an input field after clicking a button

When I try to add a field on Button Click, the default field is not showing and does not get added upon button click I have put in my best effort but I cannot figure out what the problem is. I have added functions and used Math to generate a unique id. Th ...