0đź‘Ť
If I understand, you want to display a list of the same component that take :num
as a prop.
First, you have to keep in mind that Vue is a “Data driven application”, wich means that you need to represent your list as Data in an array
or an object
, in your case you can use a myList
array and v-for
loop to display your child components list in the template.
The add and remove operations must be donne on the myList
array it self, once done, it will be automatically applied on your template.
- To add a new instance just use
myList.push(n)
- To remove an instance use
myLsit.splice(myLsit.indexOf(n), 1);
The result should look like this :
<template>
<input v-model="inputId" />
<button @click="addItem(inputId)">Add Item</button>
<childComponent
v-for="itemId in myList"
:key="itemId"
:ref="'cc' + itemId"
:num="itemId"
@kill="removeItem(itemId)"
/>
</template>
<script>
data(){
return{
inputId : 0,
myList : []
}
},
methods:{
addItem(id){
this.myList.push(id)
},
removeItem(id){
this.myLsit.splice(this.myLsit.indexOf(id), 1)
}
}
</script>
Ps :
- Didn’t test the code, if there is any error just tell me
@kill
method must be emitted by thechildComponent
,$emit('kill', this.num)
- Here is an excellent tutorial to better understand
v-for
0đź‘Ť
Performance Penalties
As there is only a limited possibility of ±200 elements, I highly doubt that it can cause any performance issue, and for further fine-tuning, instead of using v-show
, you can use v-if
it’ll reduce the total memory footprint, but increases the render time if you’re going to change the items constantly.
Other Approaches
If there weren’t limited possibilities of x
elements, it’d be still and v-for
having items which contain the v-if
directive.
But if the user could only see one item (or multiple but limited items) at the same time, instead of v-for
, It’d much better to directly bind the properties to the childComponent
.
For example, if the child component is a modal that’ll be shown by the application when a user clicked on the edit button for a row of a table. Instead of having x
number of modals, each having editable contents of a row and showing the modal related to the edit button, we can have one modal and bind form properties to it. This approach usually implemented by having a state management library like vuex
.
Finally, This is an implementation based on vuex
, that can be used, if the user could only see one childComponent
at the same time, it can be easily extended to support multiple childComponent
viewed at the same time.
store.js
export Store {
state: {
childComponentVisible: false,
childComponentNumber: 0
},
mutations: {
setChildComponentNumber(state, value) {
if(typeof value !== 'number')
return false;
state.childComponentNumber = value;
},
setChildComponentVisibility(state, value) {
if(typeof value !== 'boolean')
return false;
state.childComponentVisible = value;
}
}
}
child-component.vue
<template>
<p>
{{ componentNumber }}
<span @click="close()">Close</span>
</p>
</template>
<script>
export default {
methods: {
close() {
this.$store.commit('setChildComponentVisibility', false);
}
}
computed: {
componentNumber() {
return this.$store.state.childComponentNumber;
}
}
}
</script>
list-component.vue
<template>
<div class="list-component">
<button v-for="n in [1,2,3,4,5]" @click="triggerChildComponent(n)">
{{ n }}
</button>
<childComponent v-if="childComponentVisible"/>
</div>
</template>
<script>
export default {
methods: {
triggerChildComponent(n) {
this.$store.commit('setChildComponentNumber', n);
this.$store.commit('setChildComponentVisibility', true);
}
},
computed: {
childComponentVisible() {
return this.$store.state.childComponentVisible;
}
}
}
</script>
Note: The code written above is abstract only and isn’t tested, you might need to change it a little bit to make it work for your own situation.
For more information on vuex
check out its documentation here.