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
相关产品推荐
相关产品推荐

