Search code examples
javascriptvue.jsvue-props

Emitting data from child to parent component in Vue js


I am trying to emit data from child to the parent component but for some reason its not showing me, although I have console logged the emit and its working. Emit is being triggered but in the parent method it's not showing anything. Help me out on this one please

This is my child component i.e. Student.vue

<template>
  <div>
    <input type="text" v-model="name" />
    <button @click="addName">Add Student</button>
  </div>
</template>

<script>
export default {
  name: "Student-",
  data() {
    return {
      name: "",
    };
  },
  props: ["Name", "Program"],
  emits: ["addStudent"],
  methods: {
    addName() {
      console.log("Hello", this.name);
      this.$emit("addStudent", this.name);
    },
  },
};
</script>

<style>
.input-student {
  display: flex;
  flex-direction: column;
  width: 500px;
  justify-content: center;
  align-items: center;
  margin-left: 500px;
}

.submit-btn {
  display: flexbox;
  margin-top: 30px;
  text-align: center;
  cursor: pointer;
}
</style>

<template>
  <h2>Students</h2>
  <ul>
    <Student
      v-for="student in students"
      :key="student"
      v-on="$emit(receiveStudent)"
      {{
      students
      }}
    />
  </ul>
  <!-- <button @click="deleteStudent(index)">Delete</button> -->
</template>

<script>
import Student from "./Student.vue";

export default {
  name: "University-",
  data() {
    return {
      students: [],
    };
  },
  components: { Student },
  methods: {
    receiveStudent(name) {
      console.log("Recieving Student", name);
      // this.students.push(name);
      // console.log("Updated students array", this.students);
    },
    // deleteStudent(index) {
    //   this.students.splice(index, 1);
    // },
    // localStorageSave() {
    //   localStorage.setItem("students", JSON.stringify(this.students));
    // },
  },
  // mounted() {
  //   this.students = JSON.parse(localStorage.getItem("students")) || [];
  // },
};
</script>

<style></style>


Solution

  • The v-on needs the event name, and does not need another $emit unless you intend to re-emit the event to a grandparent component. See the Vue event handling docs. It should be

    <Student
      v-on:addStudent="receiveStudent"
    />
    

    Or short-hand

    <Student
      @addStudent="receiveStudent"
    />
    

    Other errors that need to be corrected:

    1. {{ students }} is called text interpolation and goes in between tags, not inside tags. Something like <div>{{ students }}</div> would make more sense if you want to display the entire array of students.

    2. You are not sending any actual props down to the Student. Based on Student.vue having props "name" and "program" you would pass down these props from the Parent like so:

    <Student
      v-for="student in students"
      :key="student"
      :name="student.name"
      :program="student.program"
      @addStudent="receiveStudent"
    >
    

    Vue Playground example with corrected code