Dynamically load a vuejs library and display the component within it

I've set up a Vue.js app to act as a container for multiple other "apps". The goal was to:

  • have a reusable codebase for discovering/loading components
  • develop the other apps as Vue.js libraries to allow component loading

In my first library, I have a main.js file:

import HelloRadar from './components/HelloRadar.vue'
export default HelloRadar

and the HelloRadar component:

<template>
  <div>
    Hello from radar !
  </div>
</template>

<script>
export default {
  name: 'HelloRadar'
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

Now, in my main app, I have this code:

<template>
    <div>
        <ul>
            <li v-for="module in modules" :key="module" @click="loadModule(module)">
                {{ module }}
            </li>
        </ul>
    </div>
</template>

<script>

    import axios from 'axios';

    export default {
        name: 'HelloWorld',
        data() {
            return {
                modules: [],
                selectedModuleMenu: null,
                selectedModuleApp: null
            }
        },
        created: function () {
            axios.get("/orbit/api/modules").then((response) => {
                var modulesList = response.data;
                this.modules = modulesList;
            });
        },
        methods: {
            loadModule: function (moduleName) {
                this.loadExternalComponent("/modules/" + moduleName + "/" + moduleName + ".umd.js");
            },
            loadExternalComponent: function(url) {
                const name = url.split('/').reverse()[0].match(/^(.*?)\.umd/)[1];

                if (window[name]) return window[name];

                window[name] = new Promise((resolve, reject) => {
                    const script = document.createElement('script');
                    script.async = true;
                    script.addEventListener('load', () => {
                        resolve(window[name]);
                    });
                    script.addEventListener('error', () => {
                        reject(new Error(`Error loading ${url}`));
                    });
                    script.src = url;
                    document.head.appendChild(script);
                });

                return window[name];
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

The problem is that the function loadExternalComponent doesn't seem to be working. I'm getting this JavaScript error in the console:

Uncaught TypeError: Cannot read property 'createVNode' of undefined

Uncaught (in promise) TypeError: Chaining cycle detected for promise #

I found this method here

Any ideas on how to improve this kind of application? Is using libraries the right approach? Thanks for your assistance.

Answer №1

It appears that a solution to your query has been found:

To utilize components created using the Vue 3 vue-cli, it is necessary for Vue to be present in the global scope. To successfully render components loaded through the method outlined in my publication, it is essential to define window.Vue as a reference to Vue itself. Once this step is taken, everything should function as intended.

Markus Oberlehner

@moriartie (Markus Oberlehner) collaborated with @markoffden on resolving this issue: Vue 3 external component/plugin loading in runtime

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dynamically add a CSS class to the <head> tag in real

Within this function, my goal has been to dynamically append gradClass in order to apply a gradient background to a div. function applyGradient(upto) { var gradStyle = "background: -webkit-linear-gradient(left, #ff1a00 20%,#ffffff 30%);" ...

Updating node content in jsTree

As a seasoned JavaScript developer transitioning to jQuery, I have encountered an issue while working with jsTree. I am attempting to change the name of a node within the tree but have been unsuccessful so far. Despite trying various examples from differen ...

Trying out enzyme's componentDidUpdate method in ReactJS testing

I have been attempting to test the componentDidUpdate method, but I am struggling to cover it completely. This is how I am approaching the testing: it('should execute storeCardDesigns if specific conditions are met in componentDidUpdate', () ...

I am experiencing an issue where the scrolling behavior in Ionic Vuejs does not move upwards

Developing with Ionic 6 and the latest version of Vuejs, Vuejs 3 const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, scrollBehavior(to, from, savedPosition) { return savedPosition || { top: 0 } }, ...

Angular is displaying the main view two times instead of loading the appropriate template

I've encountered a perplexing issue with Angular templating - instead of loading the correct template, the main view is rendered twice. Despite investing a considerable amount of time over the past 48 hours attempting to resolve this issue, I have mad ...

Using JavaScript values within erb code

In my coding dilemma, I have a js.erb template housing this snippet: var latlng = new google.maps.LatLng(<%= session[:lat] %>, <%= session[:lng] %>); But now, I'm attempting to tackle the reverse task (embedding javascript into ruby): & ...

Having trouble establishing an HTTPS connection with a Node.js server

After connecting to my server through the console without any errors, I encountered an issue in Chrome where it displayed a message stating This site can’t provide a secure connection local host uses an unsupported protocol. Here is the code snippet: im ...

When you click on the "email" link, the Email app will automatically launch

Is there a way I can make the "EMAIL" text clickable in HTML, so that it automatically opens an email app or site and inserts the clicked email into the "To:" field? ...

Replicate styling while copying CodeMirror code

Is there a way to maintain the styling and formatting of javascript code when copying from CodeMirror? Whenever I try to copy and paste from the CodeMirror editor, the coloring and style are lost, with the content pasted as text/plain. How can I preserve ...

JavaScript array error - unrecognized symbol

Hello, I am attempting to generate an array of errors and showcase them all at once. Here is my code: if (!first_name) { var error[] = "Please fill in the Last Name"; $('#first_name').addClass('error'); } else { $('#fi ...

The issue of duplicate items being stored in an array arose when inserting a new element

I am new to angular and currently working on an application that allows users to take notes and store them in a database. However, I have encountered a problem during the note addition process. When there are no existing notes in the database and I add tw ...

I'm having trouble getting my Ajax edit code to function correctly. Can anyone offer some assistance?

I am currently working on a basic registration system that includes two forms: one for registration and another for selecting a city. I have encountered an issue where newly added cities update perfectly, but when trying to use the selected city in the reg ...

The jQuery ajax request will only display the data in the HTML once

Hey there! I am facing an issue where, when I click on my button to make an ajax request, it works perfectly and displays the data on my select item. However, on clicking the button again, the data is fetched correctly but the select item shows the data t ...

Arranging a javascript object by organizing an array as a value

Looking to organize a JavaScript Object structured as key:pair, where the pair consists of an array with 2 timestamp values. The goal is to arrange the elements so that those with the smallest numbers (earliest times) are shown first. For instance, consid ...

Is it possible for me to send transactions asynchronously using polkadot-js?

After thoroughly going through the official documentation, I stumbled upon a page discussing how to transfer using polkadot-js const transfer = api.tx.balances.transfer(BOB, 12345); const hash = await transfer.signAndSend(alice); I am curious if it' ...

React Grid by DevExtreme

Does anyone have a solution for adjusting the fontSize of the TableHeaderRow in a DevExtreme React Grid? Here is some code from a specific website () that I've been exploring: import * as React from 'react'; // Other imports... const Ad ...

Converting a JSON object into a Vue v-for friendly structure

My goal is to display data in an html table using the Vue.js v-for directive. However, I'm encountering issues with building the table. I suspect that the data format is incorrect, and I may need to manipulate it to eliminate the object layer (index o ...

In Django, the Ajax function will fail to execute if any of the required input fields are left empty

I'm currently using an AJAX function that works well when values are entered for all three fields: pname, psection, and rinput-json. However, it fails to work if any of these fields are left empty. <script type="text/javascript"> funct ...

Managing asynchronous data in various locations using Vuex modules

I'm struggling to grasp the correct usage of Vuex and whether it's necessary in my situation. Imagine I have a basic online shop consisting of two components: Product list. Product filtering. If I don't use Vuex: I can create Filtering as ...

Capturing member function details using JSDoc

Here's the code snippet I'm working with: /** This class blah blah... @constructor **/ my.namespace.ClassA = function(type) { /** This function performs an action **/ this.doSomething = function(param){ } } The class will be inc ...