Any way to dynamically add multiple Vue components within a parent Vue component?

Hello everyone,

I’m trying to create a dashboard, and I want it to load multiple widgets (Vue Components) that will interact individually with the server to display statistics and such.

I tried what was described here

But, maybe I’m not understanding how the parent -> multiple child concept works. I’m just trying to create these as the parent page loads.

A bit of code of what I have tried:

<template>
    <div class="app-body row">
        <div class="widgets">
            <!--<div v-for="(child, index) in children" key="index"></div>-->
        </div>
    </div>
</template>

displayWidget(which) {
    let Child = Vue.extend({
        name: which,
        parent: this,
        //template: this.loadFile('/src/components/widgets/'+which+'.vue'),  // tried loading a Vue file contents in              
        
    });
    new Child({
        el: $(this.$el).find('.widgets')[0],
        template: '<div style="height: 200px; width: 200px; color: yellow">Hello</div>', // tried just standard template stuff here
        render: h => h('div')
    }).$mount();

}

As soon as the parent component is created, I’m simply trying to add one widget - for now, later I want it to load up multiple widgets.

created() {
this.displayWidget(‘Device’);
}

So, any thoughts on how I can make this parent component add multiple child components and render properly within the parent’s

?

Thank you in advance,

Adrian

1 Like

You can do this with dynamic components.

<template>
    <div class="app-body row">
        <template v-for="(child, index) in children">
            <component :is="child" :key="child.name"></component>
        </template>
    </div>
</template>

See https://vuejs.org/v2/guide/components.html#Dynamic-Components

6 Likes

Thank you for the quick reply. I think I understand what you’re doing there, and I’ll give it a try.

A lame question to throw out: If I add a component to the children array, will this automatically render the new component, or do I need to do anything special to make it show the new one (along side the others that are already on the board)? Ex: component.$mount();

Thank you again, I’ll report back even if I’m successful with this. Maybe the code I end up with can help others who have the same struggle(s).

You still trying to do everything in ‘jquery’ way (DOM related). Try to think ‘data-driven’. You don’t need to mount anything, or create new instances of vue components. You only should define your data/props and template properly, vue will do everything for you. Instead using ‘displayWidget’ method, just create separated component, define it in parent ‘components’ attribute and put it in template.

1 Like

kticka - I do agree 100% with you, as I prefer data-driven. The link I provided was the only example I could find that appeared to solve my problem. I’ll see what I can figure out with your suggestion, thank you.

This is very simple example how parent/child components works. https://jsfiddle.net/Lct8uz4o/2/

If you push another object into ‘inventory’ array, vue will automatically create new instance and render it.

If your widgets have different logic, you should create separated components. Your ‘main’ component could have array of ‘enabled’ widgets, and in your template, you should use ‘v-if’ directive, to show/hide them.

2 Likes

In case anyone comes across this and is looking for an example of how to dynamically add components on the fly. https://codepen.io/getreworked/pen/XZOgbm?editors=1010

3 Likes

James thx for sample, I forked it for more complicated scenerio: https://codepen.io/glikoz/pen/qYEZEV?editors=1010

  • User can add different widget (component) to dashboard (Yes I can :))
  • All widgets depend on common parameter (I could not) (Vuex Store)

How can I implement this requirement via Vue+Vuex

It would help if you added Vuex and used the store in your Vue instance :wink: https://codepen.io/getreworked/pen/yjNBvJ?editors=1010

2 Likes