从 CDN 库动态加载 vue 组件
Posted
技术标签:
【中文标题】从 CDN 库动态加载 vue 组件【英文标题】:Load vue components from a CDN library dynamically 【发布时间】:2019-07-31 13:01:14 【问题描述】:我正在尝试使用 vue 动态加载外部库。在这种情况下,这些库有我想使用的 vue 组件。我目前的设置如下:
-
以编程方式从 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);
-
稍后在代码中,我想在组件加载完成后动态使用它:
<component :is="dynamicComponent" v-bind="componentProperties">
<!-- More things inside -->
</component>
其中dynamicComponent
是可以更改的数据属性,设置为VBtn
(也尝试过v-btn
)。
但是这种方法不起作用,因为组件尚未全局注册。
我收到以下错误:Unknown custom element: <VBtn>
。
我也试过在window.Vuetify
可用后做Vue.use(window.Veutify)
,问题仍然存在。
我也尝试过等待组件可用
waitFor(() => Vue.options.components[dynamicComponent]).then(...)
但是它永远不会进入then
函数。有趣的是,当我在控制台中输入 Vue.options.components['VBtn']
时,我确实得到了组件。
我已经为此苦苦挣扎了一段时间。任何建议、文档、参考或不同的方法都将不胜感激,请注意我需要依赖动态加载库和动态加载其组件。
提前致谢。
【问题讨论】:
【参考方案1】:以下是使用 Vuetify 的重要步骤,顺序如下:
加载vuetify.min.css
(通常在<head>
)
加载 Material Icons 字体(如果需要)
加载vue.js
加载vuetify.js
初始化您的应用程序。
最重要的是:vue.js
和 vuetify.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>
如果你真的想要/必须动态加载你的脚本,你可以把它们包装成可以解析onload
的promise。这是一个例子:
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>
【讨论】:
好的,所以我试了一下,还是不行,我的项目是用webpack打包文件的,所以之前加载vue.js和vuetify.js很难。 Vue实例初始化后是否可以这样做,还是我必须重组我的项目? 是什么阻止您将 Vue 和 Vuetify 添加到包中? 需要动态加载库(veutify 只是一个示例)。我希望人们能够在指定 CDN(或者它可以是 npm 包名称)时与不同的库进行交互 您可以创建 Vue 实例 programmatically 并将它们挂载到现有实例中。以上是关于从 CDN 库动态加载 vue 组件的主要内容,如果未能解决你的问题,请参考以下文章
Vue.js - 是不是可以使用 Javascript 动态导入从另一台服务器加载组件?