Giacomo Voß
Giacomo Voß

Reputation: 1067

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:

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.

Upvotes: 3

Views: 3251

Answers (2)

Jason S
Jason S

Reputation: 1149

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().

Upvotes: 4

Stephen Thomas
Stephen Thomas

Reputation: 14053

You might get by using http-vue-loader. It's not generally recommended for production, but your use case might make it appropriate. Obviously there will be some limitations (e.g. importing other modules)

Upvotes: 1

Related Questions