Here's how to do with createApp in Vue 3, but the context (stores, plugins, directives...) will not be kept.

Copy// DialogService.js
import { createApp } from 'vue';

export default {
  alert(text) {
    const mountEl = document.createElement('div');
    document.body.appendChild(mountEl);

    const dialog = createApp({ extends: DialogComponentDef }, {
      // props
      text,
      // events are passed as props here with on[EventName]
      onClose() {
        mountEl.parentNode.removeChild(mountEl);
        dialog.unmount();
        dialog = null;
      },
    });

    dialog.mount(mountEl);
  },
};

To keep the context, there's something more complicated that can be seen here with h and render Vue methods : https://github.com/vuejs/vue-next/issues/2097#issuecomment-709860132

Answer from darkylmnx on Stack Overflow
๐ŸŒ
Reddit
reddit.com โ€บ r/vuejs โ€บ creating components programmatically?
r/vuejs on Reddit: Creating components programmatically?
December 21, 2022 -

I use Vue3 with Vite.

I have a dozen of components, all defined as SFCs and using the composition API and the script setup syntax. They all look pretty similar to this:

<template>
    <p>My component</p>
</template>
<script setup>
    const props = defineProps({
        propA: {
            type: String,
            default: ''
        }
    });
</script>

I am trying to create instances of these components, and add them to my app, programmatically. And so far, all the methods I have read about online, fail miserably.

The most promising seem to be the one described in this comment in an issue of the official Vue GitHub. Here is how I implemented it:

var myComponentInstance = defineComponent({
    extends: myComponent,
    data: () => ({
        props: {
            propA: 'ABCDE'
        }
    })
});
createApp(TitleComponent).mount(this.$refs.container);

But even though I think I'm doing what's expected, it fails miserably and I get tons of JS errors.

Is there an easy way to create instances of various Components (providing data via props) and mount them in my app, reliably?


I figured how to do it using <component :is="type" /> and wrote this exemple.

Discussions

Programatically create and mount a component instance
What problem does this feature solve? With vue 2.x, the Vue.component() method did return a component constructor that could be used to programatically create an instance of that component: const M... More on github.com
๐ŸŒ github.com
7
August 6, 2020
How to programmatically create Vue Components indirectly
I'm attempting to add components programatically to a page in my Vue Single file Component which works beautifully if you know what you'd like to do ahead of time. In my case, the components and th... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Vue3 Creating Component Instances Programmatically
What problem does this feature solve? In vue2 it was be easy: ... More on github.com
๐ŸŒ github.com
1
October 7, 2020
vue.js - vue2 - Programmatically create component and slots - Stack Overflow
When creating vue (2.17.4) components programmatically, it does not take data from the domnode. If you use new Vue() it does. For components created using Vue.component or Vue.extend, the props and More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
CSS-Tricks
css-tricks.com โ€บ creating-vue-js-component-instances-programmatically
Creating Vue.js Component Instances Programmatically | CSS-Tricks
January 23, 2018 - I have been on a Vue.js project that required the ability to create components programmatically. By programmatically, I mean you create and insert the components completely from JavaScript, without writing anything in the template. This article aims to illustrate how different aspects of using components in a template, such as instantiation, props passing, slots, mounting, translates to JavaScript code.
๐ŸŒ
GitHub
github.com โ€บ vuejs โ€บ core โ€บ issues โ€บ 1802
Programatically create and mount a component instance ยท Issue #1802 ยท vuejs/core
August 6, 2020 - const app = Vue.createApp({}); const MyComponent = app.component('my-component', { template: '<div>Hello {{name}}</div>', props: ['name'] }); const myComponent = new MyComponent({ propsData: { name: 'Thomas' } }); myComponent.$mount('#my-component-mountpoint');
Author ย  mofux
Top answer
1 of 2
4

It turns out that Vue has <component :is="yourComponentType"> which does exactly what I was hoping to accomplish if you throw it into a v-for loop. Documents here.

2 of 2
2

You can use Async components to retrieve a component via an API.

I've tested with GraphQL via Axios but it should work with any REST service.

The main component looks like that:

<template>
  <div>
    <h1>Test page</h1>
    <div><button @click="clicked = true">Load component</button></div>
    <async-component v-if="clicked" />
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      clicked: false,
    };
  },
  components: {
    'async-component': () => axios.post('http://localhost:5000/graphql', { query: `
      {
        asyncComponentByRowId(rowId: 1) {
          component
          content
        }
      }
    `,
    }).then((response) => {
      const comp = response.data.data.asyncComponentByRowId.content;
      // eval can be harmful
      return eval(`(${comp})`);
    }),
  },
};
</script>

The retrieved component is in the following format:

{
  "data": {
    "asyncComponentByRowId": {
      "component": "my-async-component",
      "content": "{\r\n\ttemplate: '<div>{{ msg }}</div>',\r\n\tdata: function() {\r\n\t\treturn {\r\n\t\t\tmsg: 'Async component works!'\r\n\t\t};\r\n\t}\r\n}"
    }
  }
}

The decoded data.asyncComponentByRowId.content property is a string representing a JavaScript object:

{
  template: '<div>{{ msg }}</div>',
  data: function() {
    return {
      msg: 'Async component works!'
    };
  }
}

When the button is pressed, the component is shown after being downloaded from the API asynchronously.

The only problem is that I'm using eval to decode the object.

Result:

๐ŸŒ
GitHub
github.com โ€บ vuejs โ€บ core โ€บ issues โ€บ 2331
Vue3 Creating Component Instances Programmatically ยท Issue #2331 ยท vuejs/core
October 7, 2020 - import Button from 'Button.vue' import Vue from 'vue' var ComponentClass = Vue.extend(Button) var instance = new ComponentClass() instance.$mount() // pass nothing this.$refs.container.appendChild(instance.$el) extend create instance. But in vue3 it's has been deleted. Where are another way? Like vue2 ยท ๐Ÿ‘React with ๐Ÿ‘4adamberecz, Calvin-2DWeb, anafro and arthabus ยท
Author ย  art2limit
๐ŸŒ
GitHub
github.com โ€บ vuejs โ€บ rfcs โ€บ discussions โ€บ 582
Improve rendering vue components programmatically ยท vuejs/rfcs ยท Discussion #582
Render and mount a vue component inside a specific dom element programmatically. Easly update its props and propely utilize vue's diffing algorithm to update the mounted component template.
Author ย  vuejs
Find elsewhere
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 75757648 โ€บ vue2-programmatically-create-component-and-slots
vue.js - vue2 - Programmatically create component and slots - Stack Overflow
You can also create dynamic components this way iterating over component props with v-for. ... Vue.component('Test',{ name: 'Test', props: ['prop'], template: ` <div class="hello"> SLOTCONTENT: <slot name="name">default from template</slot><br> PROPS: {{$props}} </div>` }); new Vue({el:'#app'}) <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.7.14/vue.min.js"></script> <div id="app"> Component created with new Vue() <Test id="el1" prop="el1prop"> <template #name>el1 (from markup)</template> </Test> <br> <Test id="el2" prop="el2prop"> <template #name>el2 (from markup)</template> </Test> <br> <Test id="el3" prop="el3prop"> <template #name>el3 (from markup)</template> </Test> </div>
๐ŸŒ
Devshive
devshive.tech โ€บ link โ€บ bjuzubxle โ€บ creating-vuejs-component-instances-programmatically
Creating Vue.js Component Instances Programmatically | Devs' Hive
February 24, 2019 - ...it fails. We need a class. Or, in simple terms, a constructor function. The way to do that is to pass the component object to Vue.extend to create a subclass of the Vue constructor.
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Learn_web_development โ€บ Core โ€บ Frameworks_libraries โ€บ Vue_first_component
Creating our first Vue component - Learn web development | MDN
Create a <script></script> section below your template section. Inside the <script> tags, add a default exported object export default {}, which is your component object. ... We can now begin to add actual content to our ToDoItem. Vue templates are currently only allowed a single root element ...
๐ŸŒ
YouTube
youtube.com โ€บ overseas media
Vue: Mount a component programmatically (4 lines of code) - YouTube
Jump to 5:05 for the actual code. This video will show you how to mount a component in Vue programmatically for whatever reason you wanna do that, i explain ...
Published ย  April 15, 2020
Views ย  674
Top answer
1 of 4
12

1) Since you're manually instantiating that component and it doesn't belong to your main app's component tree, the store won't be automatically injected into it from your root component. You'll have to manually provide the store to the constructor when you instantiate the component ..

import ProjectRow from "./ProjectRow.vue";
import Vue from "vue";
import store from "../store";

let ProjectRowClass = Vue.extend(ProjectRow);
let ProjectRowInstance = new ProjectRowClass({ store });

2) In a Vue Single File Component (SFC), outside of the default export this doesn't refer to the Vue instance, so you don't have access to $refs or any other Vue instance property/method. To gain access to the Vue instance you'll need to move this line this.$refs.container.appendChild(instance.$el) somewhere inside the default export, for example in the mounted hook or inside one of your methods.

See this CodeSandbox for an example of how you may go about this.

2 of 4
2

This is another way to instantiate a component in Vue.js, you can use two different root elements.

// Instantiate you main app
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

//
// Then instantiate your component dynamically
//

// Create a component or import it.
const Hello = {
  props: ['text'],
  template: '<div class="hello">{{ text }}</div>',
};

// Create a componentClass by Vue.
const HelloCtor = Vue.extend(Hello);

// Use componentClass to instantiate your component.
const vm = new HelloCtor({
  propsData: {
    text: 'HI :)'
  }
})
// then mount it to an element.
.$mount('#mount');


๐ŸŒ
Vue.js
vuejs.org โ€บ guide โ€บ essentials โ€บ component-basics
Components Basics | Vue.js
You can also use the is attribute to create regular HTML elements. When switching between multiple components with <component :is="...">, a component will be unmounted when it is switched away from. We can force the inactive components to stay "alive" with the built-in <KeepAlive> component. If you are writing your Vue templates directly in the DOM, Vue will have to retrieve the template string from the DOM.
๐ŸŒ
Reddit
reddit.com โ€บ r/vuejs โ€บ vue3 - how to create component instances programmatically?
r/vuejs on Reddit: Vue3 - How to create component instances programmatically?
August 23, 2020 -

I'm porting some old code that is basically this:

import Modal from 'Modal.vue'
import Vue from 'vue'
var ComponentClass = Vue.extend(Modal)
var instance = new ComponentClass({
    propsData: { title: 'title' }
})
instance.$mount() // pass nothing
this.$refs.container.appendChild(instance.$el)

I can't seem to find a way to get this working using Vue3.
Vue.extend has been removed, as far as I can see there's now defineComponent, but it does not seem to work the same way.

I get the following error when I just try and replace it 1-1: TypeError: ComponentClass is not a constructor

Has anyone tried something similar, or know how to fix this?

๐ŸŒ
Vue.js
v2.vuejs.org โ€บ v2 โ€บ guide โ€บ components
Components Basics โ€” Vue.js
Upgrade to Vue 3 or learn more about | Vue 2 EOL. ... Join the Vue.js Community! ... Components are reusable Vue instances with a name: in this case, <button-counter>. We can use this component as a custom element inside a root Vue instance created with new Vue:
๐ŸŒ
Telerik
telerik.com โ€บ blogs โ€บ dynamic-components-vue-component
Dynamic Components with Vue's 'component'
November 30, 2020 - In this article we will explore Vue's <component>, <keep-alive> and how to create dynamically loaded components.
๐ŸŒ
Vue.js
v2.vuejs.org โ€บ v2 โ€บ guide โ€บ components-dynamic-async
Dynamic & Async Components โ€” Vue.js
In large applications, we may need to divide the app into smaller chunks and only load a component from the server when itโ€™s needed. To make that easier, Vue allows you to define your component as a factory function that asynchronously resolves your component definition.