You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中子组件向父组件emit传值失败问题求助

Vue子组件$emit触发但父组件无响应问题排查

问题描述

在Vue.js中实现子组件向父组件传递数据时,子组件内的$emit已触发(控制台可打印相关信息),但父组件的接收方法未产生任何响应。

组件代码

子组件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>

父组件University.vue

<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>

问题根源

  • 事件绑定语法错误:父组件中v-on="$emit(receiveStudent)"是完全错误的写法,Vue监听自定义事件的正确方式是@事件名="回调方法",这里应该绑定子组件触发的addStudent事件到receiveStudent方法。
  • 模板语法违规:父组件<Student>标签内直接写入{{ students }}属于无效模板语法,会导致组件渲染异常。
  • 组件渲染逻辑错误:父组件用v-for循环渲染Student组件,但初始students数组为空,子组件根本不会被渲染,自然无法触发事件。实际应该将Student组件作为添加入口放在循环外,循环部分仅用来展示已添加的学生列表。

修复后的代码

子组件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);
      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>

父组件University.vue(核心修复)

<template>
  <div>
    <h2>Students</h2>
    <!-- 放置添加学生的子组件 -->
    <Student @addStudent="receiveStudent" />
    <!-- 循环展示已添加的学生 -->
    <ul>
      <li v-for="(student, index) in students" :key="index">
        {{ student }}
        <button @click="deleteStudent(index)">Delete</button>
      </li>
    </ul>
  </div>
</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);
    },
  },
};
</script>

<style></style>

内容的提问来源于stack exchange,提问作者Ali Haider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:46:00