多个 Vue 应用程序,多个入口文件,相同的 Vuex/Vue3CompostitionApi 存储 [失去反应性]

Posted

技术标签:

【中文标题】多个 Vue 应用程序,多个入口文件,相同的 Vuex/Vue3CompostitionApi 存储 [失去反应性]【英文标题】:Multiple Vue apps, multiple entry files, same Vuex/Vue3CompostitionApi store [lost reactivity] 【发布时间】:2021-12-14 22:36:15 【问题描述】:

我正在尝试将 .cshtml 剃须刀视图迭代地替换为我想称之为 Vue“迷你应用程序”的东西。应该介于微前端和经典 SPA 之间。目的是共享一些代码库,主要是依赖项。编译一个通用的chunk-vendors.js 并将“迷你应用程序”作为单独的 javascript 条目文件放置在适当的视图上。随着性能需求的增长,我将逐步拆分 chunk-vendors.js 并通过延迟加载进行优化。

我在这里遇到的问题是试图让两个根 Vue 实例通过共享状态相互通信。现在只有首先导入/安装的应用程序保持反应状态。我认为我的问题出在 Vue 2 反应系统/Vuex 如何将自己绑定到具体的 Vue 实例here。当我实现一个原始存储时,情况最终完全一样。

让我感到困惑的是,如果我要在一个 main.js 条目文件中实例化两个应用程序,那么商店共享就可以正常工作。这表明 Vue 要么创建某种隐藏的根实例,要么我的 Vuex 代码分析推断它绑定到具体实例是不正确的。

如果有人能告诉我为什么这行不通,我将不胜感激,可以选择建议解决方法?

我在 Vue 2 中使用 Vuex 和在 Vue 3 中使用组合 API/primitiveStoreImplementation here 创建了一个复制。 Vue-cli 以 MPA 模式构建应用程序,页面在 vue.config.json 中指定,然后导入到根 index.html 文件中。存储被初始化一次并保存以供以后在window 对象上检查/加载。在 asp/razor 的上下文中,我会设置 webpack 来删除冗余文件,只留下 javascript 包。此外,开发代理将代理除脚本包路径之外的所有内容。为了演示,所有这些都被删除了。

(一旦找到解决方案我希望将源链接替换为具体代码sn-ps)

考虑的选项:

我试图避免它,但我可能必须始终运行一个“协调器”根实例,该实例将检查页面上某些元素的存在,并使用类似 @ 的东西将“迷你应用程序”作为组件加载/卸载987654324@ 需要时。该协调器还将包含一个带有模块的状态,其中一些将被标记为“共享”,因此将允许来自多个“迷你应用程序”的操作(所有权标志检查)。

我考虑过 sessionStorage/localStorage,问题是“存储”事件仅在选项卡之间触发,而不是在一个文档 first |Note 内触发。我将不得不触发自定义事件或使用 iframe。感觉太老套了,但这可能是一个公理。它还会在许多商店实例中复制相同的状态。

以下是我在该主题上找到的一些相关文章:

可能最接近我想要实现的目标: Using Vuex with multiple Vue instances

相同但不同: Build Vue microfrontend app (with routing and vuex store)

【问题讨论】:

【参考方案1】:

多个条目的用例是在同一页面上不共存的子应用程序,尽管它们可以。它们可以是 Web 组件或常规应用程序包。他们甚至可以相互交互,但他们需要其他东西——全局事件总线或在它们之间传递数据的中介应用程序。

问题在于有多个 Vue 库副本和/或多个 Vuex 存储实例。为了避免这种情况,它们只需要在页面上精确加载一次并在应用程序之间重复使用,即 vuevuex 作为 CDN 库加载,可能用作 Webpack externals 以使用 window.Vue 和 @ 987654325@ 对各自的import 透明。不仅是 Vuex,store 也需要是页面上的单例(基本上是所说的中介)。这是可接受的解决方案,但主要适用于存在设计限制并需要解决方法的现有应用程序。

我试图避免它,但我可能必须始终运行“协调器”根实例,该实例将检查页面上某些元素的存在,并使用门户之类的组件加载/卸载“迷你应用程序”作为组件需要时 -vue。

这是执行此操作的常用方法。 Vue 3 的传送比 Portal-vue 的控制要少。如果做得好,它对应用程序设计没有任何不利之处。同样的事情在其他框架(Angular、React)中也有类似的实现,其中门户出现得更早。

我考虑过 sessionStorage/localStorage,问题是“存储”事件仅在选项卡之间触发,而不是在一个文档中触发

这可以通过在同一选项卡中使用窗口 postMessagemessage 事件来解决。如果这不应仅限于单个窗口,则有第三方库将两者都用于跨表同步,本机替代方案是 BroadcastChannel,它的浏览器支持少于 LS,但在标签方面没有限制.

【讨论】:

以上是关于多个 Vue 应用程序,多个入口文件,相同的 Vuex/Vue3CompostitionApi 存储 [失去反应性]的主要内容,如果未能解决你的问题,请参考以下文章

vue设置多个入口

一文搞懂 Webpack 多入口配置

vue项目中多个入口的配置

Vue检查多个单选按钮

从 vue-cli 到 webpack多入口打包

如何在多个域的 vue 应用上实现谷歌分析?