Passing data from a child component to a parent component in Vue using TypeScript can

I have encountered a small issue with Vue emit. While I successfully used it about a year ago, in my current project, I am struggling to make it work. Despite spending several hours trying to find a solution, I am unable to receive the emitted value in the parent component.

children:

<template>
  <v-text-field v-model="val" outlined></v-text-field>
</template>

<script lang="ts">
import { Component, Vue, Emit } from "vue-property-decorator";

@Component
export default class BasicInput extends Vue {
  val: string = "";

  @Emit()
  inputValue(): any {
    console.log("emit");
    return this.val;
  }
}
</script>

parent:

<template>
  <v-card class="mx-auto mt-2 mb-6" max-width="60%" outlined>
    <v-form>
      <BasicInput label="voting title" v-on:input-value="inputValue" />
      <BasicTextarea label="short description" />
      <BasicTextarea label="description" />
      <BasicDatepicker />
      <AddMoreInput />
      <v-btn @click="inputValue">Save</v-btn>
    </v-form>
  </v-card>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

import BasicInput from "./subcomponents/BasicInput.vue";
import BasicTextarea from "./subcomponents/BasicTextarea.vue";
import BasicDatepicker from "./subcomponents/BasicDatepicker.vue";
import AddMoreInput from "./subcomponents/AddMoreInput.vue";

@Component({
  components: {
    BasicInput,
    BasicTextarea,
    BasicDatepicker,
    AddMoreInput
  }
})
export default class AddVoting extends Vue {
  private inputValue(data: any) {
    console.log("test", data);
  }
}
</script>

In this scenario, I recall that the "data" parameter of the "inputValue" event in the parent component should be the emitter's value. However, it appears as a list of event parameters instead.

What could be causing this issue?

Answer №1

Using this code:

  <v-btn @click="inputValue">Save</v-btn>

Upon clicking the button, it activates the inputValue function. However, since the event is triggered by a click, it also passes the event parameters of that click.

This may not be what you intended; ideally, you want the input itself to trigger the event.

To achieve this, you can trigger the event by calling the child's function inputValue() from the parent component.

You can accomplish this by providing a reference to the child element:

 <BasicInput
    label="voting title"
    ref="my-input"
    v-on:input-value="inputValue"
  />

Then create a method in the parent component to emit the event from the child:

  emitEventFromInput(): void {
    this.$refs["my-input"].inputValue();
  }

Finally, call this method when you click on the button:

   <v-btn @click="emitEventFromInput">Save</v-btn>

The unchanged code for the parent component is as follows:

<template>
  <v-card class="mx-auto mt-2 mb-6" max-width="60%" outlined>
    <v-form>
      <BasicInput
        label="voting title"
        ref="my-input"
        v-on:input-value="inputValue"
      />
      <v-btn @click="emitEventFromInput">Save</v-btn>
    </v-form>
  </v-card>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

import BasicInput from "./children.vue";

@Component({
  components: {
    BasicInput,
  },
})
export default class AddVoting extends Vue {
  private inputValue(data: any) {
    console.log("value in parent =>", data);
  }
  emitEventFromInput(): void {
    this.$refs["my-input"].inputValue();
  }
}
</script>

This approach might work, but it is not considered a best practice in Vue to directly access child methods.

A more optimal solution (albeit slightly more complex) would be to implement a v-model on your component. This way, you will establish a two-way binding between the child and parent components. Refer to the documentation for detailed instructions: https://v2.vuejs.org/v2/guide/components-custom-events.html

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

Submitting an event on an Angular modal component

I recently created a modal component using the following template structure: <div class="header"></div> <div class="body"> <ng-content></ng-content> </div> <div class="footer" ...

Tips for retrieving the ID of a newly added Firestore document in Vue.js

I am currently using Vue.js and Firebase to create a very basic CRUD functionality. One issue I have encountered is that when I create data from a form and send it to the database, there is no document id available for updating my local array of objects. ...

Using VueJS: Passing a variable with interpolation as a parameter

Is there a way to pass the index of the v-for loop as a parameter in my removeTask function? I'm looking for suggestions on how to achieve this. <ol class="list-group"> <li v-for="task in tasks" class="list-group-item"> ...

Error encountered while trying to eliminate array element

I have a project in the works that involves creating a page where users can filter suggestions and vote for their favorites. The screen is divided into 3 tabs: [Top Rated], [Newest], and [My Votes]. Upon loading the screen, a call to the database is made ...

Transforming time into luxon time frames and hours

Is there a way to convert this block of code from moment.js to luxon? Here is the code snippet for reference: The following code is written using moment.js, but I would like to achieve the same functionality using luxon. timezone: null, getIn: moment() ...

Guide to implementing lazy loading and sorting in p-Table with Angular2

I recently implemented lazy loading in my application and now I am having trouble with sorting items. When lazy loading is disabled, the sorting feature works perfectly fine. However, I need help to make both lazy loading and sorting work simultaneously. C ...

How does a browser decide to load content from an http URL when the frontend source is using an https URL?

When using my Vue component to load external content in an iframe, everything works fine locally. However, once I deploy it to my HTTPS site, I encounter an issue. <iframe src="https://external-site" /> Upon deployment, I receive the following erro ...

Enumerated data utilizing the v-for directive

How do I retrieve the data in likeNEW using v-for? You need to include [0] [1]. However, it is possible to achieve this without them. Likelike(){ axios .get('http://127.0.0.1:8000/api/v1/customer/like/', { headers: { Authorizat ...

Adding animation to the initial loading process of a Vue application

I want to include an animation when the application's modules are loading for the first time. I have attempted to use an image, but I am unable to add an animation to it. Adding a CSS file did not always work as expected. I then tried utilizi ...

Is there a way to incorporate onComplete and onAbort callbacks with <router-link> similar to router.push(location, onComplete?, onAbort?)?

It is common knowledge that the onComplete and onAbort optional callbacks can be used as the 2nd and 3rd arguments in the router.push method. router.push(location, onComplete?, onAbort?) These callbacks are triggered when the navigation is either success ...

What is the best way to apply identical properties to multiple components at once?

With multiple components like <my-a>, <my-b>, and many more each having a prop: { props: { isDetail: { type: Boolean, default: false, } }, } When creating a form using these components, repeating the prop assignment becom ...

A guide on combining two counters in Vue to create a unified value

Is there a way to track the number of times two buttons are clicked individually as well as together? <div id="app"> <p><button v-on:click="counter1 += 1">Add One More Click</button></p> <p>&l ...

Display information from a JSON file using Vue.js

Hello, I am currently attempting to display data from a JSON file using Vue.js. Below is my Vue file: <template> <div> <div class="card"> <div class="card-header"> <h4 class="card-title" ...

The parameter "disabled=false" is not functioning properly in TypeScript 2.1

Struggling to deactivate a field by accessing the element ID in TypeScript 2.1. Came across this syntax for TypeScript 1.5, but unfortunately, it doesn't seem to work in 2.1. Any assistance would be greatly appreciated. ( document.getElementById(&apo ...

Ensuring proper extension of Request headers in Typescript

I am having trouble retrieving the userId from req.headers, how can I fix this issue? Initially, I attempted the following: interface ISpot{ thumbnail: File, company: string, price: number, techs: string } interface IReqCustom<T& ...

Is it possible to restrict the date range in a vuetify.js v-text-field for entering dates?

Input the date in the text field below by hand, using the MM/DD/YYYY format. Is there a way to restrict the date to a specific range using datepicker validation rules? For example, can we prevent selection of years before 1919? If the selected date fall ...

Refresh the component following a successful POST request in Vue.js

Having issues with reloading components in my VueJS app using NUXTJS. The page in my app calls a component called “CustomerCard.” When I use fetch to communicate with my API and retrieve all customers, everything works perfectly upon arriving on the p ...

Using Typescript to Import One Namespace into Another Namespace

Is it possible to export a namespace from one typescript .d.ts file and then import that namespace into another .d.ts file where it is utilized inside of a namespace? For instance: namespace_export.d.ts export namespace Foo { interface foo { ...

What is the best way to transform a JS const into TSX within a Next.js application?

Exploring the code in a captivating project on GitHub has been quite an adventure. The project, located at https://github.com/MaximeHeckel/linear-vaporwave-react-three-fiber, showcases a 3D next.js application that enables 3D rendering and animation of mes ...

What is the best way to organize objects based on their timestamps?

I am faced with the task of merging two arrays of objects into a single array based on their timestamps. One array contains exact second timestamps, while the other consists of hourly ranges. My goal is to incorporate the 'humidity' values from t ...