Vue.js数组元素无法删除问题排查求助
问题:点击删除按钮后Box元素无法移除
我一直试图找出问题所在,肯定遗漏了某些细节。参考示例代码实现功能,但点击删除按钮后目标元素并未被移除,无论添加多少个box,点击任意删除按钮都毫无反应。我尝试过使用emit函数、改用索引而非id、添加findBoxId方法(已注释报错部分),还尝试过在Box.vue中单独写方法,最后改为直接在按钮中调用emit,但都没有效果。
相关代码
App.vue
<template> <the-header title="Remember"></the-header> <new-box @add-box="addBox"></new-box> <ul> <box v-for="box in boxes" :key="box.id" :id="box.id" :name="box.name" :number="box.number" @delete="deleteBox(id)"> </box> <big-box> title="Big" info="Additional info" </big-box> </ul> </template> <script> import TheHeader from './components/layouts/TheHeader.vue'; import Box from './components/boxes/Box.vue'; import BigBox from './components/boxes/BigBox.vue'; import NewBox from './components/boxes/NewBox.vue'; export default { components: { TheHeader, Box, BigBox, NewBox }, data: () => ({ boxes: [ { id: "box one", name: "name one", number: "one" } ] }), methods: { addBox(name, number) { const newBox = { id: new Date().toISOString(), name: name, number: number }; this.boxes.push(newBox); }, findBoxId(boxId) { // const identifiedBox = this.boxes.find( (box) => box.id === boxId ); // identifiedBox(); }, deleteBox(boxId) { this.boxes = this.boxes.filter((box) => box.id !== boxId); } }, }; </script> <style> #app input { font: inherit; padding: 0.15rem; } #app label { font-weight: bold; margin-right: 1rem; width: 7rem; display: inline-block; } #app form div { margin: 1rem 0; } #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Box.vue
<template> <li> <base-card> <h3>{{ name }}</h3> <h5>{{ number }}</h5> <!-- <button @click="goRemove">Shoo away the box</button> --> <button @click="$emit('deletebox', id)">Shoo away</button> </base-card> </li> </template> <script> export default { props: [ 'id', 'name', 'number' ], emits: ['toggle-favorite', 'deletebox'], data() { return { boxItem: { id: "one", name: "box one", number: "one" }, } }, // methods: { // goRemove(boxId) { // this.$emit('deletebox', boxId); // } // } } </script> <style scoped> h3 { color: rgb(64, 17, 194); text-align: center; } li { list-style-type: none; } </style>
问题根源与修复方案
核心问题
- 事件名称不匹配:Box子组件触发的事件是
deletebox,但父组件App.vue中监听的是delete,两者名称不一致,导致父组件无法接收删除事件。 - 参数传递错误:父组件中
@delete="deleteBox(id)"里的id是未定义变量,无法正确传递要删除的Box的ID。
具体修复步骤
1. 修正App.vue的事件监听
将监听的事件名改为deletebox,并正确传递参数:
<box v-for="box in boxes" :key="box.id" :id="box.id" :name="box.name" :number="box.number" @deletebox="deleteBox"> <!-- 直接绑定方法,Vue自动传递子组件emit的参数 --> </box>
或者显式使用$event接收参数:
<box v-for="box in boxes" :key="box.id" :id="box.id" :name="box.name" :number="box.number" @deletebox="deleteBox($event)"> </box>
2. (可选)优化Box.vue的事件触发
模板中直接写$emit虽能生效,但通过方法触发更易维护:
<template> <li> <base-card> <h3>{{ name }}</h3> <h5>{{ number }}</h5> <button @click="handleDelete">Shoo away</button> </base-card> </li> </template> <script> export default { props: ['id', 'name', 'number'], emits: ['toggle-favorite', 'deletebox'], methods: { handleDelete() { this.$emit('deletebox', this.id); } } } </script>
3. 清理冗余代码
App.vue中的findBoxId方法未实际使用,可直接删除,减少代码冗余。
完成以上修改后,点击删除按钮即可触发父组件的deleteBox方法,通过filter过滤掉对应ID的元素,实现Box的删除功能。
内容的提问来源于stack exchange,提问作者Murfy
相关产品推荐
相关产品推荐

