Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue load component _completely_ dynamic

I think this is a very unusual use case, and I'm not talking about dynamically requiring components with webpack.

I want to be able to deploy "Apps" as Vue components on a completely different backend, so that the backend can return full .vue files over an API. The structure of the backend is irrelevant. So I need a way in my Vue application to achieve the following:

  • User clicks on an "app" name in the frontend Vue application
  • "app" name is async-requested at the backend
  • backend returns a .vue SFC file, with HTML, JS and CSS in it
  • frontend compiles the file to a Vue component with template and functionality
  • frontend inserts the component in the view, and the component can interact with the rest of the application (Vuex store etc.)

I found v-runtime-template which seems to be the solution for templates. But this doesn't include the JS part, does it?

Additional: I think I'm trying something like VueJS Dynamic Components, but the request URL has to be set dynamically.

like image 673
Giacomo Voß Avatar asked Apr 22 '26 23:04

Giacomo Voß


1 Answers

Markus Oberlehner has an article that I think addresses your problem. The solution is through a externalComponent(url) function that takes the place of an import() function. I've copied Markus' function here for easy reference:

// src/utils/external-component.js
export default async function externalComponent(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];
}

According to the article, you can use the externalComponent() helper function to load external components pretty much the same way as we are used to with import().

like image 111
Jason S Avatar answered Apr 24 '26 22:04

Jason S