[Vuejs]-How do I create new instances of a Vue component, and subsuqently destroy them, with methods?

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 :

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.

Leave a comment