【问题标题】:Vue load component _completely_ dynamicVue加载组件_完全_动态
【发布时间】:2019-06-30 20:01:36
【问题描述】:

我认为这是一个非常不寻常的用例,我并不是在谈论使用 webpack 动态要求组件。

我希望能够将“Apps”作为 Vue 组件部署在完全不同的后端,以便后端可以通过 API 返回完整的 .vue 文件。后端的结构无关紧要。 所以我需要在我的 Vue 应用程序中实现以下目标:

  • 用户点击前端 Vue 应用程序中的“应用”名称
  • “app”名称在后端异步请求
  • 后端返回一个.vue SFC 文件,其中包含 HTML、JS 和 CSS
  • 前端将文件编译为带有模板和功能的 Vue 组件
  • 前端将组件插入到视图中,组件可以与应用程序的其余部分(Vuex 商店等)进行交互

我找到了v-runtime-template,这似乎是模板的解决方案。但这不包括JS部分,是吗?

补充: 我想我正在尝试类似VueJS Dynamic Components 的东西,但必须动态设置请求 URL。

【问题讨论】:

  • 我在这里看到的问题是让前端解释原始 .vue 文件意味着前端必须解释该 Vue 文件具有的任何模板语法,包括 less、scss、pug、以及您的 Vue 文件可能使用的任何其他模板语言。我认为您仍然希望后端解释文件,但前端使用 Vue 组件的纯 JSON 定义。无论如何,这就是 Webpack 在幕后所做的。
  • 我可以随意扩展后端,因此可以在后端编译 pug、sass 等。但是 Vue 组件的普通 JSON 定义会是什么样子,尤其是方法和 computedProps?

标签: asynchronous vue.js


【解决方案1】:

Markus Oberlehner has an article 我认为可以解决您的问题。解决方案是通过一个 externalComponent(url) 函数代替 import() 函数。为了方便参考,我在这里复制了 Markus 的函数:

// 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];
}

根据文章,您可以使用 externalComponent() 辅助函数来加载外部组件,就像我们习惯使用 import() 一样。

【讨论】:

    【解决方案2】:

    您可能会使用http-vue-loader。通常不建议将其用于生产,但您的用例可能会使其合适。显然会有一些限制(例如importing 其他模块)

    【讨论】:

    • 如何在运行时使用 http-vue-loader 注册组件? GitHub 页面上的所有示例也在 new Vue() 构造函数中预先定义了组件。
    • 还是不知道.. 我加入了Vue.component("Test", httpVueLoader("http://localhost/Test.vue")),但什么也没发生。没有 XHR 调用,控制台中没有任何内容。我在 TypeScript 方面做错了吗?我用require("../node_modules/..:") 导入了Vue from "vue" 和httpVueLoader。
    猜你喜欢
    • 2021-02-18
    • 2020-01-21
    • 2018-07-08
    • 2019-07-31
    • 2019-06-05
    • 2019-10-28
    • 2018-01-09
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多