Can VueJS capture events emitted by a group of child components simultaneously?

I have a parent component that contains several child components.

<grid>
   <cell></cell>
   <cell></cell>
   <cell></cell>
</grid>

The child components emit an event with a payload indicating they are being edited: this.$emit('editing', cellId)

Instead of using root listeners like

<cell @editing="do something"></cell>
or EventBus.$on('editing'), I want to avoid using this.$root.$on('editing').

However, as the parent component, how can I listen for the 'editing' event when the parent component is mounted?

mounted: function(){
    this.$on('editing', doSomething)
}

Why am I unable to add a listener when the parent component is mounted?

Answer №1

The key distinction that may have eluded you can be found in the Custom Events section:

Moreover, a parent component has the ability to heed events emitted from a child component through direct use of v-on within the template where the child component is placed.

It's important to note that using $on to listen to events emitted by children is not permissible. The correct method mandates employing v-on directly in the template, as exemplified below.

This implies that communication between child and parent components transpires via a directive, utilizing the v-on (or @edit) approach.

Your provided example

mounted: function(){
    this.$on('editing',dosomething)
}

will fail to yield results. As per the emit documentation, it clarifies:

Initiate an event on the present instance.

This indicates that when operating within the same component, you are able to utilize this.$on successfully. However, for usage at the parent level, incorporation of the inline directive is essential for successful binding; otherwise, the process will fall short.

Additionally, keep in mind that emits functionality serves solely for a single step, whereby the parent can capture it. Should the need arise for emitting from subchild -> child -> parent, you must receive the event (via inline binding) from subchild within child, and subsequently emit it again to reach the parent level.

If the scenario extends beyond the child-parent arena, resorting to what is referred to as a global bus is advisable. Essentially, this streamlines all operations to a singular instance, which both emits and listens for all events. Consequently, connections are no longer confined to child-parent dynamics but instead converge onto a shared system, allowing unrestricted application across all your components.

In essence - relying on mounted for listening purposes won't yield favorable outcomes. Trust this exegesis guides you accordingly :)

Answer №2

One important distinction to make is between listening to individual children versus listening to the EventBus:

  • When you emit an event using this.$emit('event'), the event will only be triggered for the parent component.
  • On the other hand, if you use the EventBus like EventBus.$emit('event'), the event will be broadcasted to all components.

Both approaches have their advantages and disadvantages; EventBus may clutter components with unnecessary events (event pollution), while using parent event emitters may not always be as elegant as EventBus.
It ultimately comes down to your preference and needs in deciding which approach to take.

Answer №3

After encountering a similar issue, I found a solution. As others have mentioned, when you want to attach an event listener from a parent to a child component in Vue.js, you need to use v-on. This is because the child component is the one actually running the callback function when the event occurs.

Inside the child component, you can emit the event using

this.$parent.$emit('event-name');

In the parent component, you can listen for this emitted event by using:

mounted: function() {
    this.$on('event-name', function() {console.log('test')});
}  

By following the above steps, you can trigger the event in the parent component and then listen for it using $on. This allows you to establish communication between parent and child components in Vue.js.

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

Blank advertisements displayed on WordPress due to Google AdSense malfunction

My website on Wordpress can be found at . I encountered issues with the deprecated Adsense plugin for WordPress, so I created my own Adsense account. After verifying my site, I created a new ad unit and inserted its code into the body tag. The code for my ...

Retrieving Information from Ajax Call Using Python

I am struggling to figure out how to retrieve data from an Ajax request in my JavaScript code within a Python Flask application. The Ajax request I am working with does not involve jQuery. I have attempted using request.form.get() and request.get_json() i ...

javascript floating point calculation

Can anyone help me with calculating float values in JavaScript? Here is a snippet of my code: var d_val = 0.00; $.each($('.prices a b'), function(index,obj){ d_val = parseFloat( $(obj).text().replace( '€', '' ) ); ...

What is the best way to ensure that only one div is toggled at a time while using the toggle class function?

$(document).ready(function(){ $("#items").children().click(function(){ $(this).toggleClass('clicked'); }); }); .clicked { background-color:red; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></s ...

Is it possible to have multiple single page applications within a single app, or to combine history and hash routing in the same app environment?

As I work on developing my app, I have the need for multiple Vue instances across various pages of my website! I am looking to implement a combination of History routing and "hash" routing within the same app so that I can achieve URLs similar to these ex ...

Button Click Does Not Trigger Bootstrap Modal Display

This is a sample Bootstrap document that includes JS and CSS files to display a list properly in Bootstrap. However, the Modal does not appear when clicking on Launch demo modal. No JavaScript errors are displayed in the Console. Can you help troubleshoot ...

Swapping a value within an array and moving it to a new position

Consider this scenario: I am dealing with a list of arrays containing values like: let data = [ "10-45-23:45", "10-45-22:45", "10-45-20:45", "10-45-23:45", "10-45-23:59,00:00-04:59", "10-45-23:59, 0 ...

What is the purpose of having a constructor in Typescript when an interface is already used for a class?

Is it necessary to have a constructor in my class if the class already implements an interface? It seems like redundant code to me. interface PersonInterface { firstname: string; lastname: string; email: string; } class Person implements Pe ...

Using jQuery UI Datepicker and AngularJS to create a custom dashboard in Umbraco platform

After receiving guidance from Sebastiaan forums on creating a customized dashboard, I decided to enhance the user experience by adding datepickers to two fields. This allows our users to input dates and receive results from our web services. However, upon ...

The custom created THREE.Curve is not rendering correctly

Following advice from this solution, I have implemented a linearly interpolated curve in the code below: THREE.Linear3 = THREE.Curve.create( function ( points, label /* array of Vector3 */) { this.points = (points == undefined) ? [] : points; ...

A tutorial on preventing backbone.js from automatically adding /# when a dialog is closed

Whenever I navigate back on my backbone page, it automatically adds /# to the URL. This results in loading an empty index page from the Rails home view when pressing back again. Disabling turbolinks fixed this issue for me. However, another problem arises ...

What steps should I take to resolve the "StrictMode has found deprecated findDOMNode" error?

Whenever I trigger the button to open the drawer, my console displays the warning message '' findDOMNode is deprecated in StrictMode'' The container for the button component is called Sidenav import Sidenav from './Sidenav'; ...

Tips for transforming a table column into an input field to retrieve the value and id of the field?

I have a set of data stored in the table provided below. My goal is to convert the table cell into an <input/> field once it is clicked. Following that, I want to send both the value and the id of the <input/> via an ajax request. Is this achie ...

Executing JavaScript functions within Vue JS components

I'm currently working on a project that involves Vue JS within a Laravel Project Can someone guide me on how to fetch data from another JS file? Here's what I have so far: MainComponent.vue data() { return this.getData() } DataComponent.j ...

How can I stop a table from resizing in Tailwind CSS?

So, I have created this table <table class="table-fixed border-separate border border-green-800"> <thead class="bg-indigo-800 border-b-2 border-indigo-200 w-full"> <tr> <th ...

Ways to send a variable to a component through history.replace

Is there a way to retrieve the match.chatroomId in a functional component? I am currently using history.replace to navigate to this component. Here is the code snippet: onClick = {() => history.replace(`/chat/${match.chatroomId}`)} ...

How can you convert Promise.all to a single Promise?

I have successfully implemented two API calls using Promise.all method with no issues. Even though one API call is sufficient to retrieve the results, I decided to stick with Promise.all and it's still working fine. I attempted to replace Promise.al ...

Generating arrays and datasets using the power of JavaScript and jQuery

Recently, I wrote a code to arrange points inside a table, and everything was working perfectly when I specified an arrayOfDivs: http://jsfiddle.net/u58k6/6 var arrayOfDivs = [({topPosition : 99, leftPosition: 100}),({topPosition : 150, leftPosition: 400} ...

Vue.js - experiencing issues with conditional styling not functioning as expected

Can someone help me with an issue I'm having? I've created a button with a heart symbol that is supposed to change color when clicked, but it's not working as expected. This is my current code: <template> <button v-bind: ...

Finding an Element by its Class Name

Can someone assist me in selecting an element using its class name? I currently have GWT 2.0 and I am trying to accomplish this. Your help would be greatly appreciated. Thank you ...