วิธีลบรายการออกจากอาร์เรย์ใน Vue.js


96

ฉันเพิ่งเริ่มใช้ 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

});

ฉันพยายามส่งต่อเหตุการณ์ไปยังฟังก์ชันและกว่าจะลบเหตุการณ์นั้นด้วยฟังก์ชัน slice ฉันคิดว่าเป็นรหัสสำหรับการลบข้อมูลบางส่วนออกจากอาร์เรย์ วิธีใดที่ดีที่สุดในการลบข้อมูลออกจากอาร์เรย์ด้วยปุ่ม simpleb และ onclick event คืออะไร?


คำตอบ:


156

คุณกำลังใช้spliceในทางที่ผิด

โอเวอร์โหลดคือ:

array.splice (เริ่ม)

array.splice (เริ่มต้น deleteCount)

array.splice (เริ่มต้น deleteCount, itemForInsertAfterDeletion1, itemForInsertAfterDeletion2, ... )

Start หมายถึงดัชนีที่คุณต้องการเริ่มต้นไม่ใช่องค์ประกอบที่คุณต้องการลบ และคุณควรส่งผ่านพารามิเตอร์ที่สองdeleteCountเป็น 1 ซึ่งหมายความว่า: "ฉันต้องการลบ 1 องค์ประกอบโดยเริ่มที่ดัชนี {start}"

ดังนั้นคุณควรไปกับ:

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);
}

เยี่ยมมากฉันคิดอยู่แล้วว่าฉันใช้การต่อผิด บอกหน่อยได้ไหมว่าความแตกต่างระหว่าง Splice และ Slice คืออะไร? ขอบคุณ!
Giesburts

1
แน่นอน โดยพื้นฐานแล้ว sPlice จะแก้ไขอาร์เรย์เดิมในขณะที่ slice สร้างอาร์เรย์ใหม่ ข้อมูลเพิ่มเติมที่นี่: tothenew.com/blog/javascript-splice-vs-slice
Edmundo Rodrigues

คุณสามารถใช้ $ ลบเป็นชวเลขได้เช่นกัน
Chris Dixon

2
@EdmundoRodrigues ขอบคุณสำหรับสิ่งนี้ ' คุณสามารถกำหนดตัวแปรดัชนีได้ที่v-for ' :) ฉันรัก SO เพราะอัญมณีเช่นนี้
Valentine Shi

@ Edmundo Rodrigues ขอบคุณ มันดีจริงๆ ฉันแค่ลบด้วยดัชนีแทนที่จะเป็นดัชนีของวัตถุ ขอบคุณมาก
priya_21

72

คุณยังสามารถใช้. $ delete:

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

แหล่งที่มา:


4
นี่เป็นวิธีที่ถูกต้องตั้งแต่แจ้งให้ Vue รู้เกี่ยวกับข่าว
ประทับตรา

1
เหตุใดในเอกสารจึงกล่าวว่า "คุณแทบไม่จำเป็นต้องใช้" เป็นแนวทางปฏิบัติที่ดีหรือไม่?
Miguel Stevens

@Notflip: โดยปกติคุณจะแทนที่อาร์เรย์ทั้งหมด
Katinka Hesselink

1
เหตุใดจึงไม่เป็นคำตอบที่ยอมรับเมื่อ array.splice ไม่ทำงานใน vue @Gijsberts
yellowsir

1
@ Roberto slice และ splice แตกต่างกัน :)
Evil Pigeon

27

อย่าลืมผูกคีย์แอตทริบิวต์มิฉะนั้นรายการสุดท้ายจะถูกลบเสมอ

วิธีที่ถูกต้องในการลบรายการที่เลือกออกจากอาร์เรย์:

เทมเพลต

<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

คุณสามารถลบรายการผ่าน id

<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)

startIndex เริ่มจาก 0


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.