Vue.js의 배열에서 항목을 제거하는 방법


88

저는 vue.js (2)를 처음 사용하고 현재 간단한 이벤트 앱을 작업 중입니다. 이벤트를 추가했지만 이제는 버튼을 클릭하여 이벤트를 삭제하고 싶습니다.

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

});

나는 이벤트를 함수에 전달하려고 시도했고 슬라이스 함수로 그 이벤트를 삭제하는 것보다 배열에서 일부 데이터를 삭제하는 코드라고 생각했습니다. simpleb 버튼과 onclick 이벤트로 배열에서 데이터를 삭제하는 가장 깨끗한 방법은 무엇입니까?


답변:


147

splice잘못된 방식으로 사용 하고 있습니다.

과부하는 다음과 같습니다.

array.splice (시작)

array.splice (start, deleteCount)

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

시작은 제거 할 요소가 아니라 시작하려는 색인을 의미합니다. 그리고 두 번째 매개 변수 deleteCount를 1로 전달해야 합니다. 이는 "인덱스 {start}에서 시작하는 1 개의 요소를 삭제하고 싶습니다"를 의미합니다.

따라서 다음을 사용하는 것이 좋습니다.

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

또한 매개 변수를 사용하고 있으므로 this.event.

그러나 이런 식으로 indexOf모든 삭제에서 불필요한 것을 찾을 수 있습니다.이 문제를 해결하기 위해에서 index변수를 정의한 v-for다음 이벤트 객체 대신 전달할 수 있습니다.

그건:

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

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

과:

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

대단해, 이미 스플 라이스를 잘못 사용하고 있다고 생각했습니다. 스플 라이스와 슬라이스의 차이점이 무엇인지 말씀해 주시겠습니까? 감사!
Giesburts

1
확실한. 기본적으로 sPlice는 원래 배열을 수정하고 slice는 새 배열을 만듭니다. 여기에 더 많은 정보 : tothenew.com/blog/javascript-splice-vs-slice
Edmundo 로드리게스

$ remove를 속기로 사용할 수도 있습니다.
Chris Dixon

2
@EdmundoRodrigues, 감사합니다. ' 당신은v-for ' 에서 인덱스 변수를 정의 할 수 있습니다 .
Valentine Shi

@ Edmundo Rodrigues 감사합니다. 정말 좋았어요. 객체의 색인 대신 색인으로 삭제했습니다. 많이 감사합니다
priya_21

62

. $ delete를 사용할 수도 있습니다.

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

출처 :


4
이것은 Vue가 뉴스에 대해 알 수 있기 때문에 올바른 방법입니다.
insign

1
문서에 "거의 사용이 거의 필요하지 않습니다"라는 문구가 나오는 이유는 무엇입니까?
Miguel Stevens

@Notflip : 일반적으로 배열 전체를 교체합니다.
Katinka Hesselink

1
array.splice가 vue에서 작동하지 않는데 왜 이것이 허용되지 않는 대답입니까? @Gijsberts
yellowsir

1
@Roberto 슬라이스와 스플 라이스가 다릅니다. :)
Evil Pigeon

26

속성 을 바인딩하는 것을 잊지 마십시오. 그렇지 않으면 항상 마지막 항목이 삭제됩니다.

배열에서 선택한 항목을 삭제하는 올바른 방법 :

주형

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

스크립트

deleteItem(index) {
  this.items.splice(index, 1); \\OR   this.$delete(this.items,index)
 \\both will do the same
}

이것은 정말로 선택된 대답이어야합니다. 왜 옵션 (splice 또는 $ delete)도 작동하지 않는지 궁금했고 적절한 키 세트가없는 것으로 나타났습니다.
Lunyx

글쎄, 확실히 삭제되었지만 바인딩이 아직 제자리에 있지 않았을 때 이상한 일을 시작했습니다.
DZet

1
마지막 요소가 항상 삭제 된 이유를 궁금해하면서 4 시간을 보냈습니다. 감사합니다!
Carol-Theodor Pelu

6

입력으로 할 때 더 재미 있습니다. 삽입 및 삭제 옵션을 사용하여 Vue2에서 수행하는 방법에 관심이 있다면 예제를 참조하십시오.

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/vue@2.5.3/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>


도움이되지만 도와 주실 수 있나요? component를 사용할 때 막혔습니다. codepen.io/wall-e/pen/dQrmpE?editors=1010
w411 3

3

아이디를 통해 항목을 삭제할 수 있습니다.

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

JS 코드 내부

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

Vue는 관찰 된 배열의 변형 메서드를 래핑하여 뷰 업데이트도 트리거합니다. 자세한 내용을 보려면 여기클릭하십시오 .

이로 인해 Vue가 기존 DOM을 버리고 전체 목록을 다시 렌더링한다고 생각할 수 있습니다. 다행히도 그렇지 않습니다.


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

그리고 JS :

this.listaTareas = this.listaTareas.filter(i=>i.id != id)

1
당신의 대답은 다른 사람들과 거의 같으며 다른 사람들보다 낫지 않습니다. 그래서 이것을 게시하는 것은 가치가 없습니다.
foxiris

0

Splice는 특정 인덱스에서 요소를 제거하는 가장 좋은 방법입니다. 주어진 예제는 콘솔에서 테스트되었습니다.

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

startingIndex는 0부터 시작합니다.


0

다음과 같이 모두 함께 방법을 생략하지 않는 이유는 무엇입니까?

v-for="(event, index) in events"
...
<button ... @click="$delete(events, index)">
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.