Cómo eliminar un elemento de una matriz en Vue.js

88

Soy nuevo en vue.js (2) y actualmente estoy trabajando en una aplicación de eventos simple. Me las arreglé para agregar eventos, pero ahora me gustaría eliminar eventos basándome en hacer clic en un botón.

HTML

    <div class="list-group">

        <div class="list-group-item" v-for="event in events">
            <h4 class="list-group-item-heading">
                {{ event.name }}
            </h4>

            <h5>
                {{ event.date }}
            </h5>

            <p class="list-group-item-text" v-if="event.description">{{ event.description }}</p>

            <button class="btn btn-xs btn-danger" @click="deleteEvent(event)">Delete</button>
        </div>

    </div>
</div>

JS (Vue)

new Vue ({
    el: '#app',

    data: {
        events: [
            {
                id: 1,
                name: 'Event 1',
                description: 'Just some lorem ipsum',
                date: '2015-09-10'
            },
            {
                id: 2,
                name: 'Event 2',
                description: 'Just another lorem ipsum',
                date: '2015-10-02'
            }
        ],

        event: { name: '', description: '', date: '' }
    },

    ready: function() {

    },

    methods: {

        deleteEvent: function(event) {
                this.events.splice(this.event);
        },

        // Adds an event to the existing events array
        addEvent: function() {
            if(this.event.name) {
                this.events.push(this.event);
                this.event = { name: '', description: '', date: '' };
            }
        }

    } // end of methods

});

Intenté pasar el evento a la función y luego eliminar ese con la función de corte, pensé que era ese código para eliminar algunos datos de la matriz. ¿Cuál es la mejor y más limpia forma de eliminar datos de la matriz con un botón simpleb y un evento onclick?

Giesburts
fuente
¿Responde esto a tu pregunta? ¿Cómo eliminar un elemento específico de la matriz?
ponury-kostek

Respuestas:

147

Lo estás usando splicede forma incorrecta.

Las sobrecargas son:

array.splice (inicio)

array.splice (inicio, deleteCount)

array.splice (inicio, deleteCount, itemForInsertAfterDeletion1, itemForInsertAfterDeletion2, ...)

Inicio significa el índice que desea iniciar, no el elemento que desea eliminar. Y debe pasar el segundo parámetro deleteCountcomo 1, lo que significa: "Quiero eliminar 1 elemento comenzando en el índice {inicio}".

Así que es mejor que vayas con:

deleteEvent: function(event) {
  this.events.splice(this.events.indexOf(event), 1);
}

Además, está utilizando un parámetro, por lo que accede a él directamente, no con this.event.

Pero de esta manera buscará innecesario indexOfen cada eliminación, para resolver esto puede definir la indexvariable en su v-for, y luego pasarla en lugar del objeto de evento.

Es decir:

v-for="(event, index) in events"
...

<button ... @click="deleteEvent(index)"

Y:

deleteEvent: function(index) {
  this.events.splice(index, 1);
}
Edmundo Rodrigues
fuente
Impresionante, ya pensé que estaba usando el empalme incorrecto. ¿Puede decirme cuál es la diferencia entre empalmar y cortar? ¡Gracias!
Giesburts
1
Por supuesto. Básicamente, sPlice modifica la matriz original, mientras que slice crea una nueva matriz. Más información aquí: tothenew.com/blog/javascript-splice-vs-slice
Edmundo Rodrigues
También puede usar $ remove como abreviatura.
Chris Dixon
2
@EdmundoRodrigues, gracias por este ' puedes definir la variable de índice en tuv-for ' :) Me encanta SO por esas gemas.
Valentine Shi
@ Edmundo Rodrigues Gracias. Fue muy bueno. Solo estaba eliminando con el índice en lugar del índice del objeto. muchas gracias
priya_21
62

También puede usar. $ Delete:

remove (index) {
 this.$delete(this.finds, index)
}

fuentes:

Katinka Hesselink
fuente
4
Esta es la manera correcta ya que le informamos a Vue sobre las noticias.
insign
1
¿Por qué dice en la documentación "rara vez debería necesitar usarlo", es una buena práctica?
Miguel Stevens
@Notflip: por lo general, solo reemplazará la matriz como un todo.
Katinka Hesselink
1
¿Por qué esta no es la respuesta aceptada, cuando array.splice no funciona en vue? @Gijsberts
yellowsir
1
@Roberto rebanada y empalme son diferentes :)
Evil Pigeon
26

No olvide vincular el atributo de clave; de ​​lo contrario, siempre se eliminará el último elemento

Forma correcta de eliminar el elemento seleccionado de la matriz:

Modelo

<div v-for="(item, index) in items" :key="item.id">
  <input v-model="item.value">
   <button @click="deleteItem(index)">
  delete
</button>

guión

deleteItem(index) {
  this.items.splice(index, 1); \\OR   this.$delete(this.items,index)
 \\both will do the same
}
Afraz Ahmad
fuente
Esta debería ser realmente la respuesta seleccionada. Me preguntaba por qué ninguna de las opciones (empalmar o $ eliminar) funcionaba y resulta que no tenía un conjunto de claves adecuado.
Lunyx
Bueno, definitivamente eliminó algo, pero comenzó a hacer cosas raras cuando el enlace aún no estaba en su lugar.
DZet
1
Pasé 4 horas preguntándome por qué siempre se eliminaba el último elemento. ¡Gracias por esto!
Carol-Theodor Pelu
6

Es incluso más divertido cuando lo haces con entradas, porque deberían estar vinculadas. Si está interesado en cómo hacerlo en Vue2 con opciones para insertar y eliminar, consulte un ejemplo:

por favor, echa un vistazo a un violín js

new Vue({
  el: '#app',
  data: {
    finds: [] 
  },
  methods: {
    addFind: function () {
      this.finds.push({ value: 'def' });
    },
    deleteFind: function (index) {
      console.log(index);
      console.log(this.finds);
      this.finds.splice(index, 1);
    }
  }
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
  <h1>Finds</h1>
  <div v-for="(find, index) in finds">
    <input v-model="find.value">
    <button @click="deleteFind(index)">
      delete
    </button>
  </div>
  
  <button @click="addFind">
    New Find
  </button>
  
  <pre>{{ $data }}</pre>
</div>

Yevgeniy Afanasyev
fuente
esto es útil, pero ¿puedes ayudarme con esto? Me quedé atascado al usar el componente .. codepen.io/wall-e/pen/dQrmpE?editors=1010
w411 3 de
3

Puede eliminar el artículo a través de la identificación

<button @click="deleteEvent(event.id)">Delete</button>

Dentro de su código JS

deleteEvent(id){
  this.events = this.events.filter((e)=>e.id !== id )
}

Vue envuelve los métodos de mutación de una matriz observada para que también activen actualizaciones de vista. Haga clic aquí para obtener más detalles.

Puede pensar que esto hará que Vue deseche el DOM existente y vuelva a representar la lista completa; afortunadamente, ese no es el caso.

Masum Billah
fuente
1
<v-btn color="info" @click="eliminarTarea(item.id)">Eliminar</v-btn>

Y para tu JS:

this.listaTareas = this.listaTareas.filter(i=>i.id != id)
Claudio Scheuermann
fuente
1
Tu respuesta es casi la misma que la de los demás y no mejor que otras. Entonces no vale la pena publicar esto.
foxiris
0

El empalme es el mejor para eliminar un elemento de un índice específico. El ejemplo dado se prueba en la consola.

card = [1, 2, 3, 4];
card.splice(1,1);  // [2]
card   // (3) [1, 3, 4]
splice(startingIndex, totalNumberOfElements)

startIndex comienza desde 0.

Kaushik shrimali
fuente
0

¿Por qué no omitir el método todos juntos como:

v-for="(event, index) in events"
...
<button ... @click="$delete(events, index)">
James Jones
fuente