Jak usunąć element z tablicy w Vue.js.

88

Jestem nowym użytkownikiem vue.js (2) i obecnie pracuję nad prostą aplikacją do obsługi wydarzeń. Udało mi się dodać wydarzenia, ale teraz chciałbym je usunąć, klikając przycisk.

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

});

Próbowałem przekazać zdarzenie do funkcji, a potem usunąć to za pomocą funkcji slice, pomyślałem, że to ten kod do usuwania niektórych danych z tablicy. Jaki jest najlepszy i najczystszy sposób na usunięcie danych z tablicy za pomocą przycisku simpleb i zdarzenia onclick?

Giesburts
źródło
Czy to odpowiada na twoje pytanie? Jak usunąć określony element z tablicy?
ponury-kostek

Odpowiedzi:

147

Używasz splicew niewłaściwy sposób.

Przeciążenia to:

array.splice (początek)

array.splice (start, deleteCount)

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

Początek oznacza indeks, który chcesz uruchomić, a nie element, który chcesz usunąć. Drugi parametr należy przekazać deleteCountjako 1, co oznacza: „Chcę usunąć 1 element zaczynający się od indeksu {start}”.

Więc lepiej idź z:

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

Ponadto używasz parametru, więc masz do niego bezpośredni dostęp, a nie za pomocą this.event.

Ale w ten sposób przy indexOfkażdym usunięciu sprawdzisz, co jest niepotrzebne, aby rozwiązać ten problem, możesz zdefiniować indexzmienną u siebie v-for, a następnie przekazać ją zamiast obiektu zdarzenia.

To jest:

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

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

I:

deleteEvent: function(index) {
  this.events.splice(index, 1);
}
Edmundo Rodrigues
źródło
Świetnie, już myślałem, że źle używam splotu. Czy możesz mi powiedzieć, jaka jest różnica między łączeniem a plasterkiem? Dzięki!
Giesburts
1
Pewnie. Zasadniczo sPlice modyfikuje oryginalną tablicę, podczas gdy plasterek tworzy nową tablicę. Więcej informacji tutaj: tothenew.com/blog/javascript-splice-vs-slice
Edmundo Rodrigues
Możesz też użyć $ remove jako skrótu.
Chris Dixon
2
@EdmundoRodrigues, dzięki za to jedno „ możesz zdefiniować zmienną indeksu u siebiev-for ” :) Uwielbiam TAK za takie perełki.
Valentine Shi
@ Edmundo Rodrigues Dzięki. Bylo bardzo fajnie. Po prostu kasowałem za pomocą indeksu zamiast indeksu obiektu. wielkie dzięki
priya_21
62

Możesz także użyć. $ Delete:

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

źródła:

Katinka Hesselink
źródło
4
To jest właściwy sposób, ponieważ niech Vue wie o nowościach.
insign
1
dlaczego w dokumentacji jest napisane „rzadko trzeba go używać”, czy jest to dobra praktyka?
Miguel Stevens
@Notflip: zwykle po prostu zastąpisz tablicę jako całość.
Katinka Hesselink
1
dlaczego nie jest to akceptowana odpowiedź, skoro array.splice nie działa w vue? @Gijsberts
yellowsir
1
@Roberto Slice and splice są różne :)
Evil Pigeon
26

Nie zapomnij powiązać atrybutu klucza, w przeciwnym razie zawsze zostanie usunięty ostatni element

Poprawny sposób usunięcia wybranego elementu z tablicy:

Szablon

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

scenariusz

deleteItem(index) {
  this.items.splice(index, 1); \\OR   this.$delete(this.items,index)
 \\both will do the same
}
Afraz Ahmad
źródło
To naprawdę powinna być wybrana odpowiedź. Zastanawiałem się, dlaczego żadna z opcji (splice lub $ delete) nie działa i okazuje się, że po prostu nie mam odpowiedniego zestawu kluczy.
Lunyx
Cóż, na pewno coś zostało usunięte, ale po prostu zaczął robić dziwne rzeczy, gdy wiązanie nie było jeszcze na miejscu.
DZet
1
Spędziłem 4 godziny zastanawiając się, dlaczego ostatni element był zawsze usuwany. Dziękuję Ci za to!
Carol-Theodor Pelu
6

Jeszcze zabawniej jest, gdy robisz to z nakładami, ponieważ powinny być one związane. Jeśli interesuje Cię, jak to zrobić w Vue2 z opcjami wstawiania i usuwania, zobacz przykład:

proszę spojrzeć i skrzypce 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
źródło
to jest pomocne, ale czy możesz mi w tym pomóc? Utknąłem
w411 3
3

Możesz usunąć przedmiot poprzez identyfikator

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

Wewnątrz twojego kodu JS

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

Vue opakowuje metody mutacji obserwowanej tablicy, aby wyzwalały również aktualizacje widoku. Kliknij tutaj, aby uzyskać więcej informacji.

Możesz pomyśleć, że spowoduje to, że Vue wyrzuci istniejący DOM i ponownie wyrenderuje całą listę - na szczęście tak nie jest.

Masum Billah
źródło
1
<v-btn color="info" @click="eliminarTarea(item.id)">Eliminar</v-btn>

A dla twojego JS:

this.listaTareas = this.listaTareas.filter(i=>i.id != id)
Claudio Scheuermann
źródło
1
Twoja odpowiedź jest prawie taka sama jak u innych i nie lepsza od innych. Więc nie warto tego publikować.
foxiris
0

Splice najlepiej usunąć z określonego indeksu. Podany przykład jest testowany na konsoli.

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

startIndex zaczyna się od 0.

Kaushik shrimali
źródło
0

Dlaczego nie po prostu pominąć całej metody, na przykład:

v-for="(event, index) in events"
...
<button ... @click="$delete(events, index)">
James Jones
źródło