多个 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 存储实例。为了避免这种情况,它们只需要在页面上精确加载一次并在应用程序之间重复使用,即 vue
和 vuex
作为 CDN 库加载,可能用作 Webpack externals
以使用 window.Vue
和 @ 987654325@ 对各自的import
透明。不仅是 Vuex,store
也需要是页面上的单例(基本上是所说的中介)。这是可接受的解决方案,但主要适用于存在设计限制并需要解决方法的现有应用程序。
我试图避免它,但我可能必须始终运行“协调器”根实例,该实例将检查页面上某些元素的存在,并使用门户之类的组件加载/卸载“迷你应用程序”作为组件需要时 -vue。
这是执行此操作的常用方法。 Vue 3 的传送比 Portal-vue 的控制要少。如果做得好,它对应用程序设计没有任何不利之处。同样的事情在其他框架(Angular、React)中也有类似的实现,其中门户出现得更早。
我考虑过 sessionStorage/localStorage,问题是“存储”事件仅在选项卡之间触发,而不是在一个文档中触发
这可以通过在同一选项卡中使用窗口 postMessage
和 message
事件来解决。如果这不应仅限于单个窗口,则有第三方库将两者都用于跨表同步,本机替代方案是 BroadcastChannel
,它的浏览器支持少于 LS,但在标签方面没有限制.
【讨论】:
以上是关于多个 Vue 应用程序,多个入口文件,相同的 Vuex/Vue3CompostitionApi 存储 [失去反应性]的主要内容,如果未能解决你的问题,请参考以下文章