从提供给 Vue 的 Vuex 访问 instance/service (Vue.js 3)

Access instance/service from Vuex that was provided to Vue (Vue.js 3)

背景

考虑以下因素:

// app.js
import API from 'utils/API';

const api = new API(config.app.urls.api, endpoints, token);

app.provide('$api', api);

根据我在过去 24 小时内阅读的所有内容,以上是向 Vue.js 提供 'service' 的建议方法 3.

但是,上面的问题是我现在无法访问 API 实例,因为 inject 方法不能在 Vue 组件之外使用。

因此,当我想将 API 实例导入我的 Vuex 模块时,我不能...

问题

有没有 'advised' 方法可以在 Vue 组件之外访问提供的服务?或者下面是我提出的解决方案之一应该如何完成?

可能的解决方案

建议的解决方案 1

我们可以像这样将它添加到全局属性中,而不是向 Vue 提供服务:

// app.js
app.config.globalProperties.$api = api;

然后我们可以在商店中像这样访问它:

// some-vuex-module.js
import { getCurrentInstance } from 'vue';

const api = getCurrentInstance().appContext.config.globalProperties.$api;

我在我的应用程序中使用上面的方法来处理某些事情,但是对于 API 服务,这样做似乎是错误的。

建议的解决方案 2

我想到的另一个解决方案是让 API 实例对 window 可用,如下所示:

// app.js
import API from 'utils/API';

const api = window.api = new API(config.app.urls.api, endpoints, token);

app.provide('$api', api);

虽然以上看起来像是反模式...

模块化环境(通常是 Vue 3 设置)中的首选方法是只在使用它的地方导入 api,无论它是在组件内部还是外部使用。

Vue 全局 属性 的解决方案起源于 Vue 应用程序不一定是模块化的,因此它们依赖 Vue 实例作为全局应用程序范围。目前它仅适用于主要在模板中使用并且需要样板代码来导入和公开它们的属性。例子是 $t in vue-i18n.

provide/inject的解决方案适用于需要依赖注入的情况。一个常见的情况是需要松散耦合依赖关系的库。另一个是依赖关系取决于组件层次结构,并且可能因组件而异。

应避免使用 window 的解决方案,除非应用程序被划分为无法通过通用 JS 模块进行交互的单独脚本。即使那样,问题是定义全局变量的脚本应该在使用它的脚本之前加载。