【问题标题】:Load dynamically a vuejs library and render the component on it动态加载 vuejs 库并在其上渲染组件
【发布时间】:2020-09-22 15:31:05
【问题描述】:

我有一个 vuejs 应用程序作为多个其他“应用程序”的容器。 这个想法是:

  • 有一个通用代码来发现/加载组件
  • 将其他应用构建为 vuejs lib,以便能够在其上加载组件

在我的第一个库中,我有这个 main.js:

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

还有这个组件,HelloRadar:

<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>

现在,在我的主应用程序上,我有以下代码:

<template>
    <div>
        <ul>
            <li v-for="module in modules" v-bind: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>

问题是函数 loadExternalComponent 似乎不起作用。我在控制台中收到了这个 js 错误:

未捕获的类型错误:无法读取未定义的属性“createVNode”

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

我从这里https://markus.oberlehner.net/blog/distributed-vue-applications-loading-components-via-http/选择了这个方法

您知道如何制作这种应用程序吗?使用 lib 是正确的方法吗?感谢您的帮助

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    我认为你的问题有答案:

    通过 Vue 3 vue-cli 构建的组件依赖于 Vue 在 全局范围。所以为了渲染通过 我的文章中描述的技术,您需要将 window.Vue 设置为 引用 Vue 本身。然后一切都按预期工作。

    马库斯·奥伯莱纳

    @moriartie (Markus Oberlehner) 已经与 @markoffden 解决了这个问题:Vue 3 external component/plugin loading in runtime

    【讨论】:

    • 谢谢 Muka,但是我现在想知道如何访问 Vue 实例,因为在 Vue3 中,vue 中没有 Vue 对象?
    猜你喜欢
    • 2018-10-20
    • 1970-01-01
    • 2019-04-03
    • 2019-08-09
    • 1970-01-01
    • 2018-11-18
    • 2020-01-01
    • 2017-07-14
    • 2020-08-15
    相关资源
    最近更新 更多