BootstrapVue下父组件按索引删除子组件输入项仅删最后项问题咨询
问题根因
你遇到的问题核心由4个错误共同导致:
- v-for 错误使用数组索引作为
key值:Vue在列表更新时会按key复用DOM和组件实例,删除中间项后索引重排,会导致你要删除的组件没被销毁,反而最后一个组件被销毁,出现内容错位 - 父组件删除逻辑顺序颠倒:你先修改了父组件的
inputs数组,导致$refs已经更新,后续取到的索引对应的子组件已经不是你要删除的目标 - 子组件输入框未绑定
v-model:输入的内容仅存于DOM节点上,组件复用后DOM内容不会自动匹配数据 - 子组件
deleteThisFromParent中splice未传参数:无参数的splice不会修改数组,你看到的删除最后一项完全是组件复用的假象
修复方案
1. 父组件(parent.vue)修改
核心是把v-for的key改为唯一标识,调整删除逻辑顺序
<template> <div> <!-- key改为唯一id,不使用索引 --> <div class="inputArea mt-2" v-for="(item, indexParent) in inputs" :key="item.id"> <div class="col-md-12"> <b-button-group> <b-button class="col-md-6" v-b-toggle="'newInput' + item.id" variant="danger">Input</b-button> <b-button class="col-md-6" @click="deleteThis(indexParent)" variant="danger">Delete</b-button> </b-button-group> </div> <!-- key用唯一id,绑定的collapse id也用item.id避免重复 --> <child :indexParent="indexParent" :collapseId="item.id" ref="ChildComponent" /> </div> <div class="mt-3 mb-3 ml-3 mr-3"> <b-button @click="addThis()" variant="success">Add Input</b-button> </div> </div> </template> <script> import child from './child.vue' export default { name: "parent", components: { child, }, data() { return { // 每个项新增唯一id作为标识 inputs: [{ id: Date.now() }], }; }, methods: { deleteThis(indexParent) { // 先操作要删除的子组件,再修改父组件数组 this.$refs.ChildComponent[indexParent].deleteThisFromParent() this.inputs.splice(indexParent, 1); }, addThis() { // 新增时生成唯一id this.inputs.push({ id: Date.now() }); }, }, }; </script>
2. 子组件(child.vue)修改
核心是输入框绑定v-model,内部列表也用唯一id作为key,修复splice删除逻辑
<template> <b-collapse visible :id="'newInput' + collapseId" class="mt-2"> <!-- key用唯一id,不使用索引,输入框绑定v-model --> <div v-for="(item, indexChild) in inputs" :key="item.id"> <table class="table table-striped mt-2"> <tbody> <h5 class="ml-1">Input Informations</h5> <tr> <div class="mt-2">Input</div> <b-form-input v-model="item.value"></b-form-input> </tr> </tbody> </table> </div> <b-button @click="addInputInfo()">Add Input Informations</b-button> </b-collapse> </template> <script> export default { name: "child", props: ["indexParent", "collapseId"], data() { return { // 每个输入项新增唯一id和存储输入内容的value字段 inputs: [{ id: Date.now(), value: '' }], }; }, methods: { deleteThisFromParent() { // 如果是删除整个子组件不需要操作内部数组,子组件会随父组件数组删除自动销毁 // 如果是要删除子组件内部指定索引的输入项,按如下写法传索引即可: // this.inputs.splice(要删除的索引, 1) }, addInputInfo() { this.inputs.push({ id: Date.now(), value: '' }); }, }, }; </script>
额外说明
如果你的需求是删除子组件内部的某个输入项而非删除整个子组件,只需要在子组件的删除按钮中传递要删除的索引到deleteThisFromParent方法,执行splice(索引,1)即可。
内容的提问来源于stack exchange,提问作者patrick96
相关产品推荐
相关产品推荐

