Home > OS >  Vue does not correctly remove item from vfor
Vue does not correctly remove item from vfor

Time:11-16

I have this custom component in vue callled "dm-vehicle-spec"

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

which looks like the following

<script>

export default {
    props: ["spec"],

    data() {
        return {
            specName: null,
            specValue: null,
        }
    },

    mounted() {
        if (this.spec.detail_name && this.spec.detail_value) {
            this.specName = this.spec.detail_name;
            this.specValue = this.spec.detail_value;
        }
    },  

    computed: {
        getSpecNameInputName() {
            return `spec_${this.spec.id}_name`;
        },

        getSpecValueInputName() {
            return `spec_${this.spec.id}_value`;
        },
    },

    methods: {
        _handleRemoveSpec() {
            this.$emit("_handleRemoveSpec", this.spec.id);
        }
    },
}

</script>

<template>
    <div >
        <div >
            <input placeholder="Naam" type="text" :id="getSpecNameInputName"  v-model="specName">
        </div>
        <div >
            <input placeholder="Waarde" type="text" :id="getSpecValueInputName"  v-model="specValue">
        </div>
        <div @click="_handleRemoveSpec" >
            <i ></i>
        </div>
    </div>
</template>

so when i have 3 specs, 1 from the database and 2 customs i have the following array vehicleSpecs (Which i loop over)

[
   {"id":23,"vehicle_id":"1","detail_name":"Type","detail_value":"Snel","created_at":"2022-11-07T19:06:26.000000Z","updated_at":"2022-11-07T19:06:26.000000Z","deleted_at":null}, 
   {"id":24},
   {"id":25}
]

enter image description here

so lets say i want to remove the second item from the list so the one with test1 as values, then the array looks like

[{"id":23,"vehicle_id":"1","detail_name":"Type","detail_value":"Snel","created_at":"2022-11-07T19:06:26.000000Z","updated_at":"2022-11-07T19:06:26.000000Z","deleted_at":null},{"id":25}]

So the second array item is removed and thats correct because object with id 24 no longer exsist but my html shows

enter image description here

that the value for object with id 24 still exists but the value for object with id 25 is removed, how is that possible?

If u need any more code or explaination, let me know

Any help or suggestions are welcome!

CodePudding user response:

Index is not a good choice to use as v-for key. Indexes are changing when you delete something from array. Try using another property as a key.

CodePudding user response:

Run the loop in reverse order. This way, deleted items do not effect the remaining item indexes

Hit: indexReverse = list.length - index

CodePudding user response:

Try to watch on prop changes:

Vue.component('dmVehicleSpec', {
  template: `
    <div >
      <div >
        <input placeholder="Naam" type="text" :id="getSpecNameInputName"  v-model="specName">
      </div>
      <div >
        <input placeholder="Waarde" type="text" :id="getSpecValueInputName"  v-model="specValue">
      </div>
      <div @click="handleRemoveSpec" >del
        <i ></i>
      </div>
    </div>
  `,
  props: ["spec"],
  data() {
    return {
      specName: null,
      specValue: null,
    }
  },
  watch: {
    spec(val) {
      this.setSpec(val)
    }
  },  
  mounted() {
    this.setSpec(this.spec)
  },  
  computed: {
    getSpecNameInputName() {
      return `spec_${this.spec.id}_name`;
    },
    getSpecValueInputName() {
      return `spec_${this.spec.id}_value`;
    },
  },
  methods: {
    handleRemoveSpec() {
      this.$emit("handleremovespec", this.spec.id);
    },
    setSpec(val) {
      if (val.detail_name && val.detail_value) {
        this.specName = val.detail_name;
        this.specValue = val.detail_value;
      }
    }
  },
})
new Vue({
  el: "#demo",
  data() {
    return {
      vehicleSpecs: [{"id":23, "vehicle_id":"1" ,"detail_name":"Type", "detail_value":"Snel", "created_at":"2022-11-07T19:06:26.000000Z", "updated_at":"2022-11-07T19:06:26.000000Z", "deleted_at":null}, {"id":24, "vehicle_id":"1", "detail_name":"Type1", "detail_value":"Snel1", "created_at":"2022-11-07T19:06:26.000000Z", "updated_at":"2022-11-07T19:06:26.000000Z", "deleted_at":null}, {"id":25, "vehicle_id":"1", "detail_name":"Type2", "detail_value":"Snel2", "created_at":"2022-11-07T19:06:26.000000Z", "updated_at":"2022-11-07T19:06:26.000000Z", "deleted_at":null}]
    }
  },
  methods: {
    handleRemoveSpec(id) {
      this.vehicleSpecs = this.vehicleSpecs.filter(v => v.id !== id)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <dm-vehicle-spec @handleremovespec="handleRemoveSpec" v-for="(spec, index) in vehicleSpecs" :key="index" :spec="spec"></dm-vehicle-spec>
</div>

  • Related