简体   繁体   English

从CDN库动态加载Vue组件

[英]Load vue components from a CDN library dynamically

I'm trying to load external libraries dynamically using vue. 我正在尝试使用vue动态加载外部库。 In this case those libraries have vue components that I would like to use. 在这种情况下,那些库具有我要使用的vue组件。 My current setup is the following: 我当前的设置如下:

  1. Load the scripts programmatically from a CDN: 从CDN以编程方式加载脚本:
// The src CDN can change.
const src = 'https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js';
const newScript = document.createElement('script');
newScript.src = src;
newScript.async = false;
newScript.type = 'text/javascript';
document.body.appendChild(newScript);
  1. Later in code I would like to use a component dynamically when it is finished loading: 稍后在代码中,我想在组件加载完成后动态使用它:
<component :is="dynamicComponent" v-bind="componentProperties">
   <!-- More things inside -->
</component>

where dynamicComponent is a data property that can be changed and it is set as VBtn (have tried also v-btn ). 其中dynamicComponent是可以更改的数据属性,并且将其设置为VBtn (也尝试过v-btn )。

This approach however does not work, since components aren't yet registered globally. 但是,此方法不起作用,因为尚未在全球范围内注册组件。 I get the following error: Unknown custom element: <VBtn> . 我收到以下错误: Unknown custom element: <VBtn> I have also tried doing Vue.use(window.Veutify) after window.Vuetify is available and the problem is still present. 我也试图做Vue.use(window.Veutify)window.Vuetify可用,问题仍然存在。

I have also tried waiting for the component to be available using 我也尝试过等待组件可用

waitFor(() => Vue.options.components[dynamicComponent]).then(...)

however it never enters the then function. 但是,它永远不会进入then函数。 Interestingly enough when I put Vue.options.components['VBtn'] in the console I do get the component back. 有趣的是,当我将Vue.options.components['VBtn']放入控制台时,我确实将组件取回。

I've been struggling with this for a while. 我已经为此苦苦挣扎了一段时间。 Any suggestions, documentation, references or different approaches would be greatly appreciated, just note that I need to rely on dynamically loading libraries, and dynamically loading its components. 任何建议,文档,参考资料或其他方法都将不胜感激,请注意我需要依靠动态加载库以及动态加载其组件。

Thanks in advance. 提前致谢。

Here are the important steps of using Vuetify, in this order: 以下是按顺序使用Vuetify的重要步骤:

  • load vuetify.min.css (typically in <head> ) 加载vuetify.min.css (通常在<head>
  • load Material Icons font (if you need it) 加载Material Icons字体(如果需要)
  • load vue.js 加载vue.js
  • load vuetify.js 加载vuetify.js
  • initialize your App. 初始化您的应用程序。

Most importantly: both vue.js and vuetify.js need to be loaded before you initialize the app. 最重要的是:在初始化应用程序之前, vuetify.js需要加载vue.jsvuetify.js

 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet"> <div id="app"> <v-app> <v-content> <v-btn>Hello world</v-btn> </v-content> </v-app> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script type="application/javascript"> Vue.config.devtools = false; Vue.config.productionTip = false; </script> <script src="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js"></script> <script type="application/javascript"> window.onload = new Vue({ el: '#app' }); </script> 


If you really want/have to load your scripts dynamically, you can wrap them up as promises which resolve onload . 如果您确实希望/必须动态加载脚本,则可以将它们包装成可以解决onload promise。 Here's an example: 这是一个例子:

 const loadScript = source => new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = source; script.type = 'text/javascript'; script.onload = () => resolve(); script.onerror = event => reject(`${event.target.src} failed to load. ¯\\\\_(ツ)_/¯`); document.body.appendChild(script); }); Promise.all([ loadScript('https://cdn.jsdelivr.net/npm/vue/dist/vue.js').then(() => { Vue.config.devtools = false; Vue.config.productionTip = false; }), loadScript('https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.js') ]).then( () => new Vue({ el: '#app' }), error => console.log(error), ); 
 <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet"> <div id="app"> <v-app> <v-content> <v-btn>Hello world</v-btn> </v-content> </v-app> </div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM