在非 Vue Web 应用程序中嵌入 Vue Apps(或 Vue Web Components)

Embedding Vue Apps (or Vue Web Components) in a non Vue web application

我是 Vue 的新手,任务是创建一些 Vue 小部件,这些小部件可以嵌入到几个现有的非 Vue 遗留 Web 应用程序中。我们的想法是,我们将创建一个包含这些小部件的库,然后可以将其嵌入到任一遗留应用程序中,最终我们可能会将整个应用程序迁移到 Vue。

我一直在寻找最好的前进方向,但我有点困惑。我想这些是我的问题:

  1. 我是否需要在这里考虑 Web 组件,或者小部件可以是我们以某种方式嵌入的实际 Vue 应用程序吗?

  2. 如果小部件应创建为 Web 组件,使用 Vue/web-component-wrapper 或 vue-custom-element 库有什么区别吗?

  3. 无论选择哪个选项,我们都可以充分利用您在任何普通 Vue 应用程序中使用的功能 - Vue 路由器、用于状态管理的 Vuex 等(并且可以在这些小部件之间共享状态)?

  4. 小部件是否需要完全样式化,或者最好将组件的所有样式留给父应用程序(或两者的组合)?

我以前从未做过这样的事情(你可能会说!)所以任何指导或建议或示例指针都将不胜感激。

** 更新 **

我找到了这篇文章,我认为这是我需要前进的方向https://itnext.io/vuidget-how-to-create-an-embeddable-vue-js-widget-with-vue-custom-element-674bdcb96b97

存在三种截然不同(但非常相似)的情况:

  • web components
    它们应该是一个封装的网页片段。如果你愿意,它是 <iframe>s 的更聪明的替代品。它的主要用例(以及它的设计目的)是在页面中显示广告并保证主机不会扰乱其内部逻辑和呈现。

  • custom elements
    简单地说,这些是声明和注册的自定义 HTML 标签。使用它们的好处是能够在任何外部框架中将它们标记为 off-limits,声明:“此自定义元素不是您的自定义组件之一,对待它作为 HTML 标签".

  • framework components
    默认情况下,现代 JS 框架(Angular、React、Vue)在内部使用这种模式:它们的内部组件看起来像自定义元素(案例 2)。 但它们不是。它们只是内部约定,从未进入应用程序的 HTML 标记输出。
    以下是内部发生的情况:当模板被解析时,如果遇到未知的 HTML 元素,框架会假定它是其已注册的组件之一。如果是,则不会呈现标签。该组件的一个新实例被创建,标签被替换为组件模板的内容(或其渲染函数的结果)。
    上述所有框架,当 运行 进入未注册自定义组件的未知 html 标记时,将发出类似 的警告“嘿,你忘记注册了吗组件?”。除非它被注册为自定义元素(案例 2)——在这种情况下,他们会这样对待它:一个 HTML 标签。

Vue 可以优雅地处理上述所有问题。您为小部件选择的内容在很大程度上取决于上下文和所需的最终结果。

以下是您问题的答案:

  1. Do I need to be thinking Web Components here or can the widgets be actual Vue applications that we embed somehow?

如果您希望能够根据上下文设置 Web 组件的样式,则不应使用 Web 组件。

  1. If the widgets should be created as Web Components is there any difference between using the @vue/web-component-wrapper or the vue-custom-element library?

是的,有。 @vue/web-component-wrapper 生成网络组件(封装 DOM 框架)。
vue-custom-elements 声明并使用自定义元素(自定义 HTML 标签)。它们的内容是 HTML 标记(未封装)。使用自定义元素的优点是能够通知外部框架:不要将此自定义元素视为您自己的组件之一,它由其他东西(在我们的例子中是 Vue)处理。将其视为 HTML 标记。

  1. Whichever option we choose can we make full use of features that you would use in any normal Vue application - Vue router, Vuex for state management etc (and can state be shared across those widgets)?

是的。无论您选择哪个选项,您仍在使用 JavaScript(每个 widget/app 都可以不受限制地访问整个上下文)。您还可以将依赖项注入到您的小部件中,允许它们进行通信(通过修改相同的外部依赖项 - 路由器,状态管理模块等......)。这几乎是每个 Vue 实例正常运行的标准模式。简而言之,Vue(子)组件可以在没有父组件的情况下运行,并且本质上是一个 Vue 应用程序。 (或者,如果你愿意,每个 Vue 应用程序都是一个 Vue 实例,它的所有子组件也是 Vue 实例)。

  1. Would the widgets need to be fully styled or would it be best practice to leave all the styling of the components to the parent app (or a combination of the two)?

这完全是您的代码设计选择。在 Vue 中 scope CSS 很容易。但是从上面设计样式(DRY-er 代码)有很大的优势。此外,具有来自上下文的样式意味着应用更少 CSS 规则,尽管这很难算作性能问题。显然,考虑到第一个问题的答案。