Cách xóa một mục khỏi một mảng trong Vue.js


89

Tôi mới sử dụng vue.js (2) và tôi hiện đang làm việc trên một ứng dụng sự kiện đơn giản. Tôi đã quản lý để thêm sự kiện nhưng bây giờ tôi muốn xóa các sự kiện chỉ bằng cách nhấp vào một nút.

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

});

Tôi đã cố gắng truyền sự kiện vào hàm và hơn là xóa sự kiện đó bằng hàm Slice, tôi nghĩ rằng đó là mã để xóa một số dữ liệu khỏi mảng. Cách tốt nhất vi sạch nhất để xóa dữ liệu khỏi mảng bằng nút simpleb và sự kiện onclick là gì?


Điều này có trả lời câu hỏi của bạn không? Làm cách nào để xóa mục cụ thể khỏi mảng?
ponury-kostek

Câu trả lời:


148

Bạn đang sử dụng splicesai cách.

Quá tải là:

array.splice (bắt đầu)

array.splice (start, deleteCount)

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

Bắt đầu có nghĩa là chỉ mục mà bạn muốn bắt đầu, không phải phần tử bạn muốn loại bỏ. Và bạn nên truyền tham số thứ hai deleteCountlà 1, có nghĩa là: "Tôi muốn xóa 1 phần tử bắt đầu từ chỉ mục {start}".

Vì vậy, bạn nên đi với:

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

Ngoài ra, bạn đang sử dụng một tham số, vì vậy bạn truy cập trực tiếp vào nó, không phải với this.event.

Nhưng bằng cách này, bạn sẽ tìm kiếm không cần thiết cho indexOfmỗi lần xóa, để giải quyết vấn đề này, bạn có thể xác định indexbiến tại của mình v-for, sau đó chuyển nó thay vì đối tượng sự kiện.

Đó là:

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

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

Và:

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

Tuyệt vời, tôi đã nghĩ rằng tôi đã sử dụng sai mối nối. Bạn có thể cho tôi biết sự khác biệt giữa mối ghép và lát cắt là gì? Cảm ơn!
Giesburts

1
Chắc chắn rồi. Về cơ bản, sPlice sửa đổi mảng ban đầu, trong khi lát cắt tạo ra một mảng mới. Thông tin thêm tại đây: tothenew.com/blog/javascript-splice-vs-slice
Edmundo Rodrigues,

Bạn cũng có thể sử dụng $ remove như một cách viết tắt.
Chris Dixon

2
@EdmundoRodrigues, cảm ơn vì cái này ' bạn có thể xác định biến chỉ số tại của bạnv-for ' :) Tôi yêu SO vì những viên ngọc quý như vậy.
Valentine Shi

@ Edmundo Rodrigues Cảm ơn. Nó thật sự rất tốt. Tôi chỉ xóa bằng chỉ mục thay vì chỉ mục của đối tượng. cảm ơn rất nhiều
priya_21

64

Bạn cũng có thể sử dụng. $ Delete:

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

nguồn:


4
Đây là cách đúng đắn vì cho Vue biết tin tức.
insign

1
Tại sao trong tài liệu lại nói rằng "bạn hiếm khi cần sử dụng nó", đó có phải là cách thực hành tốt không?
Miguel Stevens

@Notflip: thường thì bạn sẽ chỉ thay thế toàn bộ mảng.
Katinka Hesselink

1
tại sao đây không phải là câu trả lời được chấp nhận, khi array.splice không hoạt động trong vue? @Gijsberts
yellowsir

1
@Roberto lát và mối nối khác nhau :)
Evil Pigeon

26

Đừng quên ràng buộc thuộc tính khóa, nếu không, mục cuối cùng sẽ luôn bị xóa

Cách đúng để xóa mục đã chọn khỏi mảng:

Bản mẫu

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

kịch bản

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

Đây thực sự nên là câu trả lời được lựa chọn. Tôi đã tự hỏi tại sao cả hai tùy chọn (splice hoặc $ delete) đều không hoạt động và hóa ra tôi không có bộ khóa thích hợp.
Lunyx

Chà, nó chắc chắn đã xóa, một cái gì đó, nhưng chỉ bắt đầu làm những điều kỳ lạ khi ràng buộc chưa được đặt ra.
DZet

1
Tôi đã dành 4 giờ để tự hỏi tại sao phần tử cuối cùng luôn bị xóa. Cảm ơn vì điều này!
Carol-Theodor Pelu

6

Nó thậm chí còn vui hơn khi bạn làm điều đó với các đầu vào, bởi vì chúng phải được ràng buộc. Nếu bạn quan tâm đến cách thực hiện trong Vue2 với các tùy chọn để chèn và xóa, vui lòng xem ví dụ:

xin vui lòng xem một js fiddle

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>


điều này rất hữu ích, nhưng bạn có thể giúp tôi về điều này không? Tôi gặp sự cố khi sử dụng component .. codepen.io/wall-e/pen/dQrmpE?editors=1010
w411 3

3

Bạn có thể xóa mục thông qua id

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

Bên trong mã JS của bạn

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

Vue bao bọc các phương thức đột biến của một mảng được quan sát để chúng cũng sẽ kích hoạt cập nhật chế độ xem. Bấm vào đây để biết thêm chi tiết.

Bạn có thể nghĩ rằng điều này sẽ khiến Vue vứt bỏ DOM hiện có và hiển thị lại toàn bộ danh sách - may mắn thay, không phải vậy.


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

Và đối với JS của bạn:

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

1
Câu trả lời của bạn gần giống với những người khác và không tốt hơn những người khác. Vì vậy, nó không xứng đáng để đăng điều này.
foxiris

0

Splice là cách tốt nhất để xóa phần tử khỏi chỉ mục cụ thể. Ví dụ đã cho được thử nghiệm trên bảng điều khiển.

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

startIndex bắt đầu từ 0.


0

Tại sao không bỏ qua tất cả các phương pháp cùng nhau như:

v-for="(event, index) in events"
...
<button ... @click="$delete(events, index)">
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.