Sharing functions as properties with child components

If I have a reusable component called Modal in my application and I want to dynamically bind functions to the Yes button, how can I pass a function to the @click event of the Yes button within the Modal as a prop? For example:

//data tags are used for fast markup here only
<template>
    <div>
        <div :id="`${id}`" data-modal>
           <div data-modal-title>
               {{title}}
           </div>
           <div data-modal-body>
               {{body}}
           </div>
           <div data-modal-footer>
               <button @click="//event to be passed//" data-modal-button-ok>Yes</button>
               <button data-modal-button-cancel>Yes</button>
           </div>
       </div>
   </div>
</template>

<script>
   export default {
       name: 'modal',
       props: [
          'id',
          'title',
          'body',
           // event?
       ]
   }
</script>

When using this modal, how should the event be passed?

<Modal id="x" title="y" body="z" //event="????"//></Modal>

Answer №1

To trigger an event (let's call it yes) in the modal, you can:

<button @click="$emit('yes')" data-modal-button-ok>Yes</button>

Alternatively, you can create a method:

<button @click="handleYesClick" data-modal-button-ok>Yes</button>
methods: {
  handleYesClick() {
    this.$emit('yes');
  }
}

In the parent component, listen for this event using:

<modal ... v-on:yes="someCodeToExecute"></modal>

or the shorthand version:

<modal ... @yes="someCodeToExecute"></modal>

Check out the demo below:

Vue.component('modal',  {
  template: "#modal",
  name: 'modal',
  props: ['id', 'title', 'body']
})
new Vue({
  el: '#app',
  data: {},
  methods: {
    methodAtParentYes() {
      alert('methodAtParentYes!');
    },
    methodAtParentCancel() {
      alert('methodAtParentCancel!');
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<template id="modal">
    <div>
        <div :id="`${id}`" data-modal>
           <div data-modal-title>
               {{title}}
           </div>
           <div data-modal-body>
               {{body}}
           </div>
           <div data-modal-footer>
               <button @click="$emit('yes')" data-modal-button-ok>Yes</button>
               <button @click="$emit('cancel')" data-modal-button-cancel>Cancel</button>
           </div>
       </div>
   </div>
</template>

<div id="app">
  <modal id="1" title="My Title" body="Body" @yes="methodAtParentYes" @cancel="methodAtParentCancel"></modal>
</div>

Answer №2

There are a couple of ways to achieve this functionality.


The first approach is to pass the method down as a prop in the Parent component and then call that prop directly in the click handler within the Modal component.

Parent.vue

<template>
   <Modal id="x" title="y" body="x" :handleYes="handleYes"></Modal>
</template>
<script>
  methods: {
    handleYes () {
      // perform desired action
    }
  }
</script>

Modal.vue

<button @click="handleYes()">Yes</button>

Another way is to utilize $emit. In the Modal.vue component, you can define a method to emit an event which can then be listened for in the Parent component where the method will be called.

Modal.vue

<template>
  <button @click="emitEvent">Yes</button> 
</template>
<script>
  methods: {
    emitEvent () {
      this.$emit('userClickedYes')
    }
  }
</script>

Parent.vue

<template>
   <Modal id="x" title="y" body="x" @userClickedYes="handleYes"></Modal>
</template>
<script>
  methods: {
    handleYes () {
      // perform desired action
    }
  }
</script>

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

Creating unsightly class names using Node.js

Is it possible to automatically create random and unattractive class names? For example, is there a tool or plugin that can substitute the .top-header class with something like .a9ev within my CSS code? It would also be ideal if the class name in the HTML ...

Display the Sencha Touch Picker with the previously selected option showing

When using the Sencha Touch Picker component, I noticed that if I select a data and then hide the picker, upon showing it again, only the first record is selected each time. I want the picker to display my last selection when shown again. To achieve this ...

Click on the link to trigger the function that retrieves the value from the element with the ID "email"

I am completely new to HTML and JavaScript and currently building a website using Wix.com. The website will only consist of a text box and a button. While Wix.com is a user-friendly site builder, it lacks full HTML editing capabilities. This means I have ...

The redirection did not occur as no authorization token was detected

I have two Nodejs applications, one for the front-end and the other for the back-end. The back-end app is secured with token access using express-jwt and jsonwebtoken middlewares. My issue is as follows: when I make a request from the front-end to the bac ...

Is there a way for one choice to influence the available answers and pricing of other selection options?

I need to create two selection boxes, one for print type and one for size. When a user selects "LUSTRE" in the first box, I want the second box to only display "17x25.5", "13x19", and "10x15" for that specific print type. The issue I'm facing is that ...

What's the most efficient method of exporting modules along with their submodules in (Vue, React)?

Looking for the most efficient method to export a module that contains submodules with the help of an index.js? I have been following a specific naming and saving convention for my web components in projects involving Vue or React. However, I am interested ...

Updating the output of a Vue3 plugin when a property is changed

I am working on displaying localized text that updates based on the selected language. To achieve this, I have developed a plugin with the following function: app.config.globalProperties.$trans = (key) => { return findTranslation(key, app.config.gl ...

Step-by-step guide on using the input tag to embed videos

I'm trying to embed a YouTube video using an iframe with an input tag, but for some reason, it's not working. Can you help me find the mistake? Here's the URL I entered: https://www.youtube.com/embed/G20AHZc_sfM This is the code in the body ...

Using a hashtag in the URL to open an HTML <div> element

I have a website with two tabs labeled as Home and Action. When I hover over the Action tab, the URL changes to include #tab_action: https://i.sstatic.net/OOD5S.png Then, when I click on it, the related tab content opens: https://i.sstatic.net/JdcGG.pn ...

Error: Attempting to access the property '_id' of an undefined variable throws a TypeError, despite having body-parser installed

I am currently learning the MEAN stack, but I have hit a roadblock with this error message: TypeError: Cannot read property '_id' of undefined. After searching online, I found suggestions that I need to include body-parser in my server.js file. H ...

Matching names with corresponding IDs from multiple arrays in React

In my React app, I am dealing with an array structure. There is one array that contains the ids of two other arrays, along with their respective names. The goal is to create a new array that combines all the necessary information. Here is a simplified vers ...

Passing dynamic modifiers in custom Vue.js directives

<Button ... v-tooltip.bottom="{ value: tooltip, disabled: !tooltip }" /> Is there a way to dynamically change the position of the tooltip from "bottom" to another modifier such as top, left, or right in PrimeVue? I have various modifi ...

I'm stumped trying to understand why I keep getting this syntax error. Any thoughts on how to fix it?

Our team is currently working on creating a dynamic SELECT box with autocomplete functionality, inspired by the Standard Select found at this link: We encountered an issue where the SELECT box was not populating as expected. After further investigation, ...

"Learn how to compile a single jade file using grunt-jade instead of compiling all files at once

In my jade.js file, the code looks like this: 'use strict'; var config = require('../config'); module.exports = { dist: { options: { pretty: true, debug: false, timestamp: '<%= new Date().getTime() %>&apo ...

What causes the DOM to be updated upon each opening of the browser extension for Chrome?

Here is the default position: https://i.stack.imgur.com/tkWCA.png After checking it: https://i.stack.imgur.com/tdzbg.png When I click anywhere on the page to hide the dom extension output (without showing popup.html); However, when I reopen the extens ...

Issue with Adding Additional Property to react-leaflet Marker Component in TypeScript

I'm attempting to include an extra property count in the Marker component provided by react-leaflet. Unfortunately, we're encountering an error. Type '{ children: Element; position: [number, number]; key: number; count: number; }' is n ...

Avoid displaying null values in SELECT and GET operations when using node-postgres

Within my Express API functionality, I aim to offer the client flexibility in providing their contact details, namely phone number or website address, with the option of leaving them blank. The SELECT queries in use are as follows: -- Retrieve all users S ...

Creating dynamic and interactive web pages can be achieved by utilizing either $_POST or $_GET with Modal,

In the snippet below, you'll find the HTML code that pulls an array of 6 objects from a database and displays them in a Bootstrap row successfully. <div class="row products"> <?php while($product = mysqli_fetch_assoc($featured)) ...

Create a BezierCurve dynamically using Three.js

I'm struggling to dynamically generate a BezierCurve from arrays in JavaScript. I tried using push method, but it's not working as expected. var x = [0,10,100,220,100, etc,...]; var y = [10,0,100,200,200, etc,...]; var z = [100,220,10,0,100, etc ...

Unlocking the Power of Combining JMVC and Server-side MVC Models

It's been a few days since I posted this question here and still no response. I also tried posting it on forum.javascriptMVC.com and finally got an answer, but I'm looking for more insights. Here's my question: After reading the documentat ...