Me pregunto cómo agregar y eliminar elementos específicos de secciones agregadas dinámicamente. Llevo una semana luchando con eso y no encuentro la solución a mi caso.
El problema se describe claramente en las imágenes. En resumen, el mayor problema es que los botones de eliminación no saben a qué elemento pertenecen.
<template> <div> <div class="section" v-for="(el, index) in sections" :key="index" > <td> SECTION:{{index}} <div class="element" v-for="(sel, index) in sections" :key="index"> <span>PICK UP YOUR ANIMAL</span> <select > <option v-for="(item, index) in zoo" :key="index" v-bind:value="item"> <option>{{item.name}}</option> </option> </select> <button class="rem el" @click='removeElement(index, el)'>-</button> </div> </td> <button class="addEleme" @click='addElement'>add element</button> <button class="rem sec" @click='removeSection'>-</button> </div> <button class="addSect" @click='addSection'>add section</button> <p>{{test}}</p> <span>{{sections}}</span> <span>{{elements}}</span> </div> </template> <script> export default { name: 'HelloWorld', data() { return { zoo: [ {name: "Crocodyle Sara"}, {name: "Elepfhant Mike"}, {name: "Lion Monika"}, {name: "Shark Robert"}, {name: "Zebra Antony"} ], sections:[], elements:[], test:"", i:1 } }, methods:{ // Sections meth //----------------------------------------// addSection(){ this.sections.push(this.zoo) this.i+=1 this.test=`gucci: check console` console.log('this.sections: ', this.sections); }, removeSection(index){ this.sections.splice(index, 1) this.test="remove section" }, // Elemnts meth //----------------------------------------// addElement(){ this.test=`not gucci: should add element` }, removeElement(index){ this.elements.splice(index, 1) this.test="not gucci should remove element" } } } </script>
Eche un vistazo a las siguientes soluciones simples con otro componente:
Vue.component('mySelect', { template: ` <div> <select v-model="selected" @change="selectAnimal"> <option disabled value="">Please select one</option> <option v-for="(item, index) in zoo" :key="index" v-bind:value="item"> {{item.name}} </option> </select> <button class="rem el" @click='remove'>remove element</button> </div> `, props: ['idx', 'el'], data() { return { zoo: [{name: "Crocodyle Sara"}, {name: "Elepfhant Mike"}, {name: "Lion Monika"}, {name: "Shark Robert"}, {name: "Zebra Antony"}], selected: '' } }, methods: { selectAnimal() { const obj = {id: this.el, ...this.selected} this.$emit('sel', obj) }, remove() { const obj = {idx: this.idx, el: this.el} this.$emit('rem', obj) } } }) new Vue({ el: "#demo", data() { return { sections: [], selected: [] } }, methods:{ newId() { return Math.floor(Date.now() / 1000) }, addSection(){ this.sections.push({id: this.newId(), elements: [this.newId()]}) }, removeSection(index){ this.sections.splice(index, 1) }, addElement(idx){ const nr = this.sections[idx].elements.length this.sections[idx].elements.push(this.newId()) }, removeElement(obj){ const elems = this.sections[obj.idx].elements const element = elems.find(e => e === obj.el) this.selected = this.selected.filter(f => f.id !== element) this.sections[obj.idx].elements = elems.filter(e => e !== element) }, handleSelect(sel) { const found = this.selected.find(s => s.id === sel.id) this.selected = this.selected.map(x => (x.id === sel.id) ? sel : x) if (!found) this.selected.push(sel) } } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="demo"> <ul class="section" v-for="(section, index) in sections" :key="index" > SECTION:{{section.id}} <li class="element" v-for="(element, idx) in section.elements" :key="idx"> <span>PICK UP YOUR ANIMAL {{element}}</span> <my-select :el="element" :idx="index" @sel="handleSelect" @rem="removeElement"></my-select> </li> <button class="addEleme" @click='addElement(index)'>add element</button> <button class="rem sec" @click='removeSection(index)'>remove section</button> </ul> <button class="addSect" @click='addSection'>add section</button> <p>Sections: {{ sections }}</p> <p>Selected: {{ selected }}</p> </div>