Get Index of an object and Delete In Vue Component

0

This is my code based on this link

But I do not get the index of the for cycle, Basically I need a button to delete the element that is clicked on.

The removeChild method does not work.

ItemClean.vue

<template>
    <li>
    <div
      :class="{bold: isFolder}"
      >
      {{model.name}}
      <span v-show="!isFolder" class="remove" @click="changeType"> [Add] </span>
      <span class="remove" @click="removeChild(index)"> [Remove] </span>
    </div>
    <ul v-if="isFolder">
      <item-clean
        class="item"
        v-for="model, index  in model.children"
        :key="index"
        :model="model"
        >
      </item-clean>
      <li class="add" @click="addChild">+</li>
    </ul>
  </li>
</template>

<script>
    export default {
        props: {
          model: Object
        },
        data () {
          return {
          }
        },
        computed: {
          isFolder: function () {
            return this.model.children &&
              this.model.children.length
          }
        },
        methods: {
            changeType: function () {
              if (!this.isFolder) {
                Vue.set(this.model, 'children', [])
                this.addChild()
              }
            },
          addChild: function () {
            this.model.children.push({
              name: 'new stuff'
            })
          },

          //Esta funcion no me sirve ya que no obtiene el index
          removeChild: function(index){
            //Vue.delete(this.model, 'name')
            this.$delete(this.model.children, index);
          },
        }

    }
</script>

<style>
    .remove, .bold{
        cursor: pointer;
    }
    .bold{
        font-weight: bold;
    }
</style>

index.html

    <ul id="item_clean">
      <item-clean
        class="item"
        :model="treeData">
      </item-clean>
    </ul>

app.js

const item_clean = new Vue({
  el: '#item_clean',
  data: {
    treeData: {
        name: 'My Tree',
        children: [
          { name: 'hello' },
          { name: 'wat' },
        ]
    }
  }
});
    
asked by ztvmark 27.09.2017 в 06:21
source

2 answers

0

Use identifiers such as UUID for each element within the data array, so that it looks like this:

[
  {
     id: 'f6148255-d61c-4240-9801-ffff1db07a1b',
     name: 'music',
     children: [
       {
         id: '09a099a7-994f-4304-ad43-8c0c5068c32c',
         name: 'Prófugos - Soda Stereo',
       },
     ],
   }
]

In this way you will have access to the uuid of each element to eliminate with more security. This will not be done in the model that you have passed, but in the parent model so that deleting the element will re-render the DOM with the updated data.

<span class="remove" @click="removeChild(model.id)">Remove</span>

In the removeChild method you make the request using a custom event for the father to remove the item in question:

removeChild(id) {
  this.$emit('remove', id); // el padre recibirá este evento
},

Finally, the parent must listen for this event. This is done using the v-on attribute:

<ul id="item_clean">
  <item-clean
    class="item"
    :model="treeData"
    v-on:remove="remove" // esto referenciará a un método 'remove'
  >
  </item-clean>
</ul>

Finally, you define the remove method in the parent element:

function remove(id) {
  const clone = Object.assign({}, this.threeData, {});
  const filter = (data = [], index = 0, id) => {
    if (index === clone.length - 1) { return; }
    const child = clone[index];

    if (child.id === id) {
      return clone.filter(c => c.id !== id);
    }

    if (child.hasOwnProperty('children')) {
      filter(child.children, id);
    } else {
      filter(clone, index + 1, id);
    }
  };
  this.threeData = filter(clone, id);
}

This last method recursively iterates the treeData and, when it finds an element that matches the id to eliminate, it eliminates and stops the execution, otherwise it looks if it has children and returns to perform the process.

    
answered by 13.10.2017 в 16:12
0

Using the value of index to remove an item from the list is not what is recommended, but if you still want to do it you have forgotten the parentheses in the html:

<item-clean
        class="item"
        v-for="(model, index)  in model.children"
        :key="index"
        :model="model"
        >
</item-clean>
    
answered by 27.10.2017 в 22:47