Vuejs 3 emit event from child to parent component

11,140

You should add the new emits option containing the emitted event names :

child :

<template>
  <div id="child">
    <button v-on:click="tryThis">Enlarge text</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "Child",
  emits: ["enlargeText"],
  methods: {
    tryThis() {
      console.log("trying");
      this.$emit("enlargeText", "someValue");
    },
  },
});
</script>

Parent :

<template>
  <div>
    <p>Container</p>
    <Child @enlargeText="onEnlargeText" />
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import Child from "./Child.vue";

export default defineComponent({
  name: "UrlContainer",
  components: {
    Child,
  },
  methods: {
    onEnlargeText() {
      console.log("enlarging text");
    },
  },
});
</script>

LIVE DEMO

Share:
11,140
Keith Darragh
Author by

Keith Darragh

Trying to solve code.

Updated on June 08, 2022

Comments

  • Keith Darragh
    Keith Darragh almost 2 years

    I've recently started working with VueJS, I'm using v3 and seem to be having an issue calling a method on a parent. The emit function in the child doesn't seem to be emitting the event and nothing is getting picked up in the parent.

    I've included the parent and child to show how I have it set up

    Parent

    <template>
      <First/>
      < Child v-bind:sample="sample" @enlarge-text="onEnlargeText"/>
    </template>
    
    <script lang="ts">
    import { defineComponent } from 'vue';
    import axios from 'axios';
    import First from './First.vue';
    import Child from './Child.vue';
    
    export default defineComponent({
      name: 'Container',
      components: {
        First,
        Child,
      },
      methods: {
        onEnlargeText() {
          console.log('enlargeText');
        },
      },
      data: () => ({
        sample: [],
        parentmessage: '',
      }),
      created() {
        axios.get('http://localhost:8080/getData')
          .then((response) => {
            console.log(response);
            this.sample = response.data;
          })
          .catch((error) => {
            console.log(error);
          });
      },
    });
    </script>
    
    

    Child

    <template>
      <div id="add">
        <form id="signup-form" @submit.prevent="submit">
          <label for="text">Text:</label>
          <input type="text" v-model="text" required>
          <p class="error" >{{ error }}</p>
          <div class="field has-text-right">
            <button type="submit" class="button is-danger">Submit</button>
          </div>
        </form>
        <button v-on:click="tryThis">
          Enlarge text
        </button>
    </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue';
    import axios from 'axios';
    
    interface SampleInterface {
      text: string;
      error: string;
    }
    
    export default defineComponent({
      name: 'Add',
      data: (): AddInterface => ({
        text: '',
        error: '',
      }),
      methods: {
        tryThis() {
          this.$emit('enlarge-text');
        },
        submit() {
          this.$emit('enlarge-text');
        },
      },
    });
    </script>
    

    How should this be done? Is there something I've missed?

    I was wondering can I still use $emit here?

  • Keith Darragh
    Keith Darragh over 3 years
    I've ran this in the demo and I don't see the 'enlarging text' output from the onEnlargeText function. I think this should be output here?
  • Boussadjra Brahim
    Boussadjra Brahim over 3 years
    It works with camelCase format please check this codesandbox.io/s/vue-3-ts-forked-3kg1q?file=/src/components/‌​…
  • Keith Darragh
    Keith Darragh over 3 years
    I haven't downvoted, don't worry you've been so helpful! Why does this need to be camelcase? In the docs it says it should be event name casing?
  • Boussadjra Brahim
    Boussadjra Brahim over 3 years
    i know that you didn't do that, i think it's a bug i post this answer in which i recommend to use cabeb-case but when i tried that with vue 3 it doesn't work
  • Keith Darragh
    Keith Darragh over 3 years
    Fair enough! This works with canal case, I'm going to mark as complete :)
  • Boussadjra Brahim
    Boussadjra Brahim over 3 years
    I will post an issue in vue-next repo
  • Boussadjra Brahim
    Boussadjra Brahim over 3 years
    this the issue that i posted