I need to target and erase a component that I duplicated using v-for
.
I’m creating a multiple stopWatch
app.
At this time I’m able to erase only the last component I duplicated but I want to be able to erase any of the components targeted
Here is my component “Counter”:
<template> <div class="chrono"> <h2><input type="text" :placeholder="'Chrono' + number" /></h2> <div class="timer"> <input type="number" v-model.number="hours">: <input type="number" v-model.number="minutes">: <input type="number" v-model.number="seconds"> </div> <div class="controls"> <button @click="handleCounter">{{ startStop }}</button> <button @click="resetCounter">reset</button> </div> <slot></slot> </div> </template> <script> export default { name: "Counter", data() { return { hours: 0, minutes: 0, seconds: 0, startStop: "start", interval: "", }; }, props:["number"], methods: { handleCounter() { if (this.startStop === "start") { this.interval = setInterval( function () { this.seconds++; if (this.seconds + 1 > 60) { this.minutes++; this.seconds = 0; } if (this.minutes + 1 > 60) { this.hours++; this.seconds = 0; this.minutes = 0; } }.bind(this), 1000 ); this.startStop = "stop"; } else if (this.startStop === "stop") { clearInterval(this.interval); this.startStop = "start"; } }, resetCounter() { this.seconds = 0; this.minutes = 0; this.hours = 0; }, }, }; </script> <style scoped lang="scss"> .chrono { border: 1px solid black; margin: auto; border-radius: 5px; } .timer{ display: flex; flex-flow: row; justify-content: center; } .timer input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } .timer input{ width: 25px; border: none; text-align: center; } </style>
and there is the App.vue where I want to duplicate or erase my Counter component:
<template> <section> <button @click="addCounter">+</button> <div class="listOfCounter" > <Counter v-for="index in count" :key="index" :number="index"> <button @click="removeCounter">-</button> </Counter> </div> </section> </template> <script> import Counter from "./components/Counter.vue"; export default { name: "App", components: {Counter}, data() { return { count: 1, index:[] }; }, methods: { addCounter() { this.count++; }, removeCounter() { this.count--; }, }, }; </script> <style lang="scss"> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Advertisement
Answer
You can convert count
to array then push/filter to add/remove counter:
Vue.component('Counter', { template: ` <div class="chrono"> <h2><input type="text" :placeholder="'Chrono' + number" /></h2> <div class="timer"> <input type="number" v-model.number="hours">: <input type="number" v-model.number="minutes">: <input type="number" v-model.number="seconds"> </div> <div class="controls"> <button @click="handleCounter">{{ startStop }}</button> <button @click="resetCounter">reset</button> </div> <slot></slot> </div> `, data() { return { hours: 0, minutes: 0, seconds: 0, startStop: "start", interval: "", }; }, props:["number"], methods: { handleCounter() { if (this.startStop === "start") { this.interval = setInterval( function () { this.seconds++; if (this.seconds + 1 > 60) { this.minutes++; this.seconds = 0; } if (this.minutes + 1 > 60) { this.hours++; this.seconds = 0; this.minutes = 0; } }.bind(this), 1000 ); this.startStop = "stop"; } else if (this.startStop === "stop") { clearInterval(this.interval); this.startStop = "start"; } }, resetCounter() { this.seconds = 0; this.minutes = 0; this.hours = 0; }, }, }) new Vue({ el: '#demo', data() { return { count: [0], index: [] }; }, methods: { addCounter() { this.count.push(Math.max(...this.count)+1); }, removeCounter(index) { console.log(this.count) this.count = this.count.filter(i => i !== index); }, }, })
#app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .chrono { border: 1px solid black; margin: auto; border-radius: 5px; } .timer{ display: flex; flex-flow: row; justify-content: center; } .timer input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } .timer input{ width: 25px; border: none; text-align: center; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="demo"> <section> <button @click="addCounter">+</button> <div class="listOfCounter" > <Counter v-for="index in count" :key="index" :number="index"> <button @click="removeCounter(index)">-</button> </Counter> </div> </section> </div>