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

Vue中v-for删除列表项后DOM显示异常问题求助

问题原因与解决方案

问题根源

  1. v-for使用index作为key导致组件复用错误
    Vue通过key值识别列表元素的唯一性,当使用数组index作为key时,删除中间元素后,后续元素的index会自动前移。比如原数组中index=1对应id=24的元素,删除后index=1变成id=25的元素,但Vue会直接复用原index=1的组件实例,不会重新创建,导致该组件仍显示原id=24的旧数据,而原index=2的组件(对应id=25)会被销毁,出现显示异常。

  2. 组件内部数据未响应prop更新
    子组件的specName和specValue仅在mounted钩子中初始化一次,当组件被复用(传入的spec prop发生变化)时,mounted不会再次执行,内部数据无法同步更新为新spec的值,进一步加剧显示错误。

解决步骤

1. 替换v-for的key为唯一标识

将父组件中v-for的key从index改为spec.id,利用每个spec的唯一id让Vue准确跟踪元素身份:

<dm-vehicle-spec 
  @_handleRemoveSpec="_handleRemoveSpec" 
  v-for="spec in vehicleSpecs" 
  :key="spec.id" 
  :spec="spec"
></dm-vehicle-spec>

2. 让组件内部数据响应prop变化

提供两种可行方案:

方案一:通过watch监听spec变化更新数据

给子组件添加watch监听spec的变化,及时更新内部数据:

<script>
export default {
  props: ["spec"],
  data() {
    return {
      specName: null,
      specValue: null,
    };
  },
  mounted() {
    this.updateSpecData();
  },
  watch: {
    spec: {
      immediate: true, // 初始化时立即执行一次
      handler(newSpec) {
        this.updateSpecData(newSpec);
      },
    },
  },
  methods: {
    updateSpecData(spec = this.spec) {
      this.specName = spec.detail_name || null;
      this.specValue = spec.detail_value || null;
    },
    _handleRemoveSpec() {
      this.$emit("_handleRemoveSpec", this.spec.id);
    },
  },
  computed: {
    getSpecNameInputName() {
      return `spec_${this.spec.id}_name`;
    },
    getSpecValueInputName() {
      return `spec_${this.spec.id}_value`;
    },
  },
};
</script>

方案二:用computed替代内部data(更推荐)

直接通过computed属性绑定prop值,天然具备响应式,无需手动监听:

<script>
export default {
  props: ["spec"],
  computed: {
    specName: {
      get() {
        return this.spec.detail_name || null;
      },
      set(value) {
        // 若需同步更新父组件的spec数据,可在此处触发事件
        // this.$emit('update-spec', { ...this.spec, detail_name: value });
      },
    },
    specValue: {
      get() {
        return this.spec.detail_value || null;
      },
      set(value) {
        // this.$emit('update-spec', { ...this.spec, detail_value: value });
      },
    },
    getSpecNameInputName() {
      return `spec_${this.spec.id}_name`;
    },
    getSpecValueInputName() {
      return `spec_${this.spec.id}_value`;
    },
  },
  methods: {
    _handleRemoveSpec() {
      this.$emit("_handleRemoveSpec", this.spec.id);
    },
  },
};
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:35:18