How to retrieve the event source from custom events within Vue components?

I am currently developing a Vue component that includes multiple child components. At any given time, only one child component is visible and the user can switch between them only when the currently visible child emits an is-valid event.

My goal is to maintain decoupling in this setup so that children remain unaware of their parent and communicate solely through event emissions. This also means that the children are oblivious to their location within the parent component.

Therefore, the parent component needs to somehow keep track of which child emitted the event. If the event originated from the correct child (the one currently visible), specific buttons should be activated to allow the user to navigate to the next or previous child.

Here is what I have implemented so far:

HTML

<div id="app">
    <template id="m-child">
        <div>
            <button v-on:click="setstate(true)">Valid</button>
            <button v-on:click="setstate(false)">Invalid</button>
        </div>
    </template>

    <template id="m-parent">
        <div>
            <m-child v-on:newstate="newchildstate"></m-child>
            <m-child v-on:newstate="newchildstate"></m-child>
            <m-child v-on:newstate="newchildstate"></m-child>
        </div>
    </template>

    <m-parent></m-parent>
</div>

JS

Vue.component('m-child', {
    template: '#m-child',
    data: function() {
        return {};
    },
    methods: {
        setstate: function (valid) {
            this.$emit('newstate', valid);
        }
    }
});

Vue.component('m-parent', {
    template: '#m-parent',
    methods: {
        newchildstate: function (valid) {
            console.log('valid:' + valid + ', but where from?');
        }
    }
});

new Vue({
    el: '#app'
});

While I could simply assign an index during the child event binding like this:

        <m-child v-on:newstate="newchildstate(0, $event)"></m-child>
        <m-child v-on:newstate="newchildstate(1, $event)"></m-child>
        <m-child v-on:newstate="newchildstate(2, $event)"></m-child>

Doing so would compromise modularity. My intention is to seamlessly plug in multiple children in the DOM and immediately enable functionality.

After reviewing the Vue events API, it appears that there is no straightforward method to identify the event source.

Answer №1

The approach to passing data back depends on your specific requirements. Personally, I prefer setting a unique id as a prop and then emitting it back using $emit:

<m-child v-on:newstate="newchildstate" :id="1"></m-child>
<m-child v-on:newstate="newchildstate" :id="2"></m-child>
<m-child v-on:newstate="newchildstate" :id="3"></m-child>

In the child component, you can emit an object containing the id and state:

Child Component:

this.$emit('newstate', {id: this.id, state: valid});

Parent Component:

newchildstate: function (valid) {
  console.log('valid:' + valid.state + ', from' + valid.id);
}

Although similar to hard coding, at some point your parent component will need to handle the event. You could set up an array in the data section with initial states and use v-for:

data: {
  children: [true, false, false] // initialize states
}

You would then iterate over the array like this:

<div v-for="(state, index) in states">
  <m-child v-on:newstate="newchildstate" :id="index"></m-child>
</div>

And in your view model:

methods: {
  newchildstate: function(valid) {
    this.$set(this.states, valid.id, valid.state);
  }
}

Here's a JSFiddle demo that dynamically initializes the array via a prop and sets up the child components: https://jsfiddle.net/2y9727e2/

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

Unable to upload any further verification documents to Stripe Connect bank account in order to activate payouts

Query - Which specific parameters should I use to generate the correct token for updating my Stripe bank account in order to activate payouts? I've attempted to activate payouts for my Stripe bank account by using a test routing and account number (t ...

Tips for transferring a form using Ajax and PHP

Just starting out with this project and hoping for some help. I need to get a simple code working first before making any modifications. Currently, the echo function is not showing anything on the page after submitting the form. My goal is to submit a form ...

Creating a captivating full-frame background video using react-vimeo or react-player: A step-by-step guide

I am currently working on embedding Vimeo videos as full-frame background videos with autoplay and loop functionalities, while hiding player controls. I managed to achieve this using a standard HTML video element, but faced challenges when attempting to im ...

Prevent selecting dates on <input type="datetime-local"> fields

How can I restrict date selection? I am working on implementing a date picker for clients to choose appointment dates. To prevent clients from selecting dates that are already booked (stored in a database and using Vue), I want to set limitations. Note: I ...

What is the best method for providing an argument to JavaScriptCore/Console through the terminal or another method?

JSC appears to be a straightforward and convenient option‒more portable, quasi-universally-installed alternative to node.js... I have managed to grasp the basics but there seems to be very minimal information available (why?), so here's an issue tha ...

Tips for implementing HTML5 validation followed by automatic redirection to a different page

I'm new to web development and struggling with how to make a button both validate inputs and redirect to another page. Using the onclick = "" function, I can validate inputs like emails and telephone numbers, but I'm having trouble making it so t ...

Making Ajax requests to a servlet from a JSP form and dynamically updating a <div> element with the response

As I navigate my way through learning about ajax, I am currently exploring how to execute an ajax call from a JSP form and then showcase the result in a designated div. The following JSP form effectively loads data into divOrderResultContainer; however, I ...

Generating ASP.NET Components Dynamically Using JavaScript

I am exploring the possibility of generating asp.net elements dynamically using javascript. Successfully creating html elements on-the-fly looks like this var _upload = document.createElement("input"); _upload.setAttribute("type", "file"); _upload.setAt ...

Is assigning key value pairs a statement in JavaScript?

I am curious to learn about the following code snippet: var a = {x:function(){},y:function(){}} Can we consider x:function(){} to be a statement within this code? ...

Using Fabric JS to update the image source of an element with a new URL

Can the src attribute of a fabric js object be changed to a CDN url? { version: '4.4.0', objects: [ { type: 'image', version: '4.4.0', originX: 'left', ... src:'www.cdn ...

Using Jquery to add new HTML content and assign an ID to a variable

Here is some javascript code that I am having trouble with: var newAmount = parseInt(amount) var price = data[0]['Product']['pris']; var id = data[0]['Product']['id']; var dat ...

How to connect an external module to NuxtJS using Vue.js

Attempting to incorporate a widget/plugin/extension system into my existing web UI built with NuxtJS. Within the pages/view.vue single-file component, I aim to establish the extension system by dynamically loading components indicated through query paramet ...

Is there a way to retrieve values from a different menu without the need to refresh the page?

Whenever a radio button is clicked on a form, a popup menu is displayed. The popup menu is implemented using the Bootstrap module. However, there is an issue where selecting an option from the popup menu causes the form to reset, resulting in the loss of ...

Perform a toggle action on the first row when clicking within the current row using Jquery

I've been grappling with the idea of creating a function that can display and hide a comment field when a button is clicked. The challenge here is that there are multiple line items with their own comment boxes. I want to find a way to achieve this wi ...

A guide to implementing a For-Each Loop on Argument Array within Functions using Java Script

My code is not functioning properly. I am trying to calculate the sum of numbers provided by the user as arguments. I have attempted to use the Argument Object, but I can't seem to figure out what mistake I've made. // The Argument Object funct ...

Switch out the "Wishlist" button for the "Add to Cart

While managing my Opencart store, I encountered a requirement to replace the "Add to Wishlist" button with an "Add to Cart" button on the product page. After making changes to the code, the appearance of the button was successfully updated. CODE ...

When trying to use bootbox.confirm within a dynamically loaded AJAX div, the modal unexpectedly opens and

I have implemented bootbox into my project, which was downloaded from . user_update.php is being loaded in a div within users.php using ajax functionality. Within user_update.php, there is a JavaScript function called validateForm(). Right after the functi ...

How can Backbone.js utilize Ajax to bind data to a Collection?

I've recently delved into the world of Backbone.js. My goal is to create a Collection and populate it with data sourced externally. The current format of the data is CSV, not JSON. I am considering converting it to JSON for simplicity. Therefore, I ...

What is the process by which Oracle HRMS retrieves the complete description of a job posting?

With my limited understanding of JavaScript, I noticed that the HRMS refreshes the page and displays the job details under the same URL as the job list page. I expected to find job detail information in the network requests, but upon inspecting them, I dis ...

I encountered an issue while starting the VueJS build where an error message appeared stating: "Conflict: Multiple assets emit

After updating VueJS this morning, my app started encountering an issue. When I try to build it, an error message pops up stating: Error: Conflict: Multiple assets emit to the same filename img/default-contractor-logo.0346290f.svg Despite there being onl ...