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”:
JavaScript
x
88
88
1
<template>
2
<div class="chrono">
3
<h2><input type="text" :placeholder="'Chrono' + number" /></h2>
4
<div class="timer">
5
<input type="number" v-model.number="hours">:
6
<input type="number" v-model.number="minutes">:
7
<input type="number" v-model.number="seconds">
8
</div>
9
<div class="controls">
10
<button @click="handleCounter">{{ startStop }}</button>
11
<button @click="resetCounter">reset</button>
12
</div>
13
<slot></slot>
14
</div>
15
</template>
16
17
<script>
18
export default {
19
name: "Counter",
20
data() {
21
return {
22
hours: 0,
23
minutes: 0,
24
seconds: 0,
25
startStop: "start",
26
interval: "",
27
};
28
},
29
props:["number"],
30
methods: {
31
handleCounter() {
32
if (this.startStop === "start") {
33
this.interval = setInterval(
34
function () {
35
this.seconds++;
36
if (this.seconds + 1 > 60) {
37
this.minutes++;
38
this.seconds = 0;
39
}
40
if (this.minutes + 1 > 60) {
41
this.hours++;
42
this.seconds = 0;
43
this.minutes = 0;
44
}
45
}.bind(this),
46
1000
47
);
48
this.startStop = "stop";
49
} else if (this.startStop === "stop") {
50
clearInterval(this.interval);
51
this.startStop = "start";
52
}
53
},
54
resetCounter() {
55
this.seconds = 0;
56
this.minutes = 0;
57
this.hours = 0;
58
},
59
},
60
};
61
</script>
62
63
<style scoped lang="scss">
64
.chrono {
65
border: 1px solid black;
66
margin: auto;
67
border-radius: 5px;
68
}
69
.timer{
70
display: flex;
71
flex-flow: row;
72
justify-content: center;
73
74
}
75
.timer input::-webkit-outer-spin-button,
76
input::-webkit-inner-spin-button {
77
78
-webkit-appearance: none;
79
margin: 0;
80
}
81
.timer input{
82
width: 25px;
83
border: none;
84
text-align: center;
85
}
86
87
</style>
88
and there is the App.vue where I want to duplicate or erase my Counter component:
JavaScript
1
45
45
1
<template>
2
<section>
3
<button @click="addCounter">+</button>
4
<div class="listOfCounter" >
5
<Counter v-for="index in count" :key="index" :number="index">
6
<button @click="removeCounter">-</button>
7
</Counter>
8
</div>
9
</section>
10
</template>
11
12
<script>
13
import Counter from "./components/Counter.vue";
14
15
export default {
16
name: "App",
17
components: {Counter},
18
data() {
19
return { count: 1,
20
index:[]
21
};
22
},
23
methods: {
24
addCounter() {
25
26
this.count++;
27
},
28
removeCounter() {
29
this.count--;
30
},
31
},
32
};
33
</script>
34
35
<style lang="scss">
36
#app {
37
font-family: Avenir, Helvetica, Arial, sans-serif;
38
-webkit-font-smoothing: antialiased;
39
-moz-osx-font-smoothing: grayscale;
40
text-align: center;
41
color: #2c3e50;
42
margin-top: 60px;
43
}
44
</style>
45
Advertisement
Answer
You can convert count
to array then push/filter to add/remove counter:
JavaScript
1
76
76
1
Vue.component('Counter', {
2
template: `
3
<div class="chrono">
4
<h2><input type="text" :placeholder="'Chrono' + number" /></h2>
5
<div class="timer">
6
<input type="number" v-model.number="hours">:
7
<input type="number" v-model.number="minutes">:
8
<input type="number" v-model.number="seconds">
9
</div>
10
<div class="controls">
11
<button @click="handleCounter">{{ startStop }}</button>
12
<button @click="resetCounter">reset</button>
13
</div>
14
<slot></slot>
15
</div>
16
`,
17
data() {
18
return {
19
hours: 0,
20
minutes: 0,
21
seconds: 0,
22
startStop: "start",
23
interval: "",
24
};
25
},
26
props:["number"],
27
methods: {
28
handleCounter() {
29
if (this.startStop === "start") {
30
this.interval = setInterval(
31
function () {
32
this.seconds++;
33
if (this.seconds + 1 > 60) {
34
this.minutes++;
35
this.seconds = 0;
36
}
37
if (this.minutes + 1 > 60) {
38
this.hours++;
39
this.seconds = 0;
40
this.minutes = 0;
41
}
42
}.bind(this),
43
1000
44
);
45
this.startStop = "stop";
46
} else if (this.startStop === "stop") {
47
clearInterval(this.interval);
48
this.startStop = "start";
49
}
50
},
51
resetCounter() {
52
this.seconds = 0;
53
this.minutes = 0;
54
this.hours = 0;
55
},
56
},
57
})
58
59
new Vue({
60
el: '#demo',
61
data() {
62
return {
63
count: [0],
64
index: []
65
};
66
},
67
methods: {
68
addCounter() {
69
this.count.push(Math.max(this.count)+1);
70
},
71
removeCounter(index) {
72
console.log(this.count)
73
this.count = this.count.filter(i => i !== index);
74
},
75
},
76
})
JavaScript
1
30
30
1
#app {
2
font-family: Avenir, Helvetica, Arial, sans-serif;
3
-webkit-font-smoothing: antialiased;
4
-moz-osx-font-smoothing: grayscale;
5
text-align: center;
6
color: #2c3e50;
7
margin-top: 60px;
8
}
9
.chrono {
10
border: 1px solid black;
11
margin: auto;
12
border-radius: 5px;
13
}
14
.timer{
15
display: flex;
16
flex-flow: row;
17
justify-content: center;
18
19
}
20
.timer input::-webkit-outer-spin-button,
21
input::-webkit-inner-spin-button {
22
23
-webkit-appearance: none;
24
margin: 0;
25
}
26
.timer input{
27
width: 25px;
28
border: none;
29
text-align: center;
30
}
JavaScript
1
11
11
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
2
<div id="demo">
3
<section>
4
<button @click="addCounter">+</button>
5
<div class="listOfCounter" >
6
<Counter v-for="index in count" :key="index" :number="index">
7
<button @click="removeCounter(index)">-</button>
8
</Counter>
9
</div>
10
</section>
11
</div>