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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:36:03