在所有 vue 组件实例之间共享变量

Posted

技术标签:

【中文标题】在所有 vue 组件实例之间共享变量【英文标题】:Sharing variable across all vue component instances 【发布时间】:2020-07-17 08:46:59 【问题描述】:

我正在尝试重构一些代码并将一些代码移动到 mixin。但我得到了不同的行为。我希望在组件的所有实例之间共享一个对象。所以我写了类似下面的东西

<script>
export default 
  registryManager: new RegistryManager()

</script>

在某些情况下,我通过this.$options.registeryManager 访问它。 现在我已将此代码移至 mixin。

混音

export default 
  registryManager: new RegistryManager()

组件

<script>
import registryManager from './mixins/registryManager';
export default 
  mixins: [registryManager]

</script>

假设您有 2 个组件 A、B。之前,组件 A 的所有实例都有一个 registryManager,组件 B 的所有实例都有一个单独的 registryManger。 使用 mixin,组件 A 和组件 B 的所有实例共享一个注册表管理器,因为无论有多少组件使用 mixin,都只会创建一个 mixin 实例 有什么方法可以为每个组件创建一个 mixin 实例以获得更早的行为?

【问题讨论】:

为您导入mixin 的每个组件创建一个新实例。所以不确定你想要达到什么目标? 不确定是不是这样。所有组件都获得相同的注册表管理器实例。 有没有更简洁的方式在组件的所有实例之间共享变量? 是的,使用像Vuex 这样的状态管理库。如果 mixin 编写正确,它们的行为类似于 pure 函数。不确定我是否理解您的问题。 它被定义为一个选项有什么原因吗?它应该在某处被覆盖吗? 【参考方案1】:

这是预期的行为。只有一个类实例,new RegistryManager() 在 mixin 模块中只评估一次,Vue 不知道registryManager 需要多次实例化。

由于组件构造函数和类实例是一一对应的关系,所以可以赋值为构造函数属性。

这可以在全局范围内完成:

Object.defineProperty(Vue.prototype, 'registryManager', 
  get() 
    if (!this.constructor._registryManager) 
      this.constructor._registryManager = new RegistryManager();
    

    return this.constructor._registryManager;
  
);

该类也以这种方式延迟实例化。可以放在install(Vue) ...里面作为插件使用。

或者在本地作为 mixin:

  beforeCreate() 
    if (!this.constructor._registryManager) 
      this.constructor._registryManager = new RegistryManager();
    

    this.registryManager = this.constructor._registryManager;
  

【讨论】:

这样会被添加到所有组件中。没有办法将它注入包含 mixin 的组件中吗?我将尝试这件作品一次,并尝试对所需的行为进行一些修改。 在全球范围内这样做可能不是一件坏事。但是,是的,它也可以是一个 mixin。【参考方案2】:

您可以在 mixin 中创建一个工厂方法,该方法需要一个 id(例如组件的名称)并返回一个 RegisterManager 的实例。

mixin 模块必须保留从 id 到 RegisterManager 实例的映射。

类似的东西。

const instances = 


export default 
  getRegistryManager: (id) => 
    if (!instances[id]) 
      instances[id] = new RegistryManager()
    

    return instances[id]
  

然后从您的组件中调用getRegistryManager

<script>
  import getRegistryManager from './mixins/registryManager';
  export default 
   mixins: [getRegistryManager("ComponentName")]
  
</script>

【讨论】:

这在任何时候都是一个不错的解决方案。但问题是我正在编写一个节点模块供其他人使用。首先,我不能要求他们做很多事情。用户不应该为创建注册表而烦恼。其次,很多用户不提供姓名或ID可能会发生冲突。

以上是关于在所有 vue 组件实例之间共享变量的主要内容,如果未能解决你的问题,请参考以下文章

C ++在更多对象实例之间共享一个变量

在 React 组件之间共享 volatile 变量 [重复]

Vue js 2 *私下*保存组件的数据

Vuex 拾遗

在所有 Vue.js 组件之间共享数据

是否可以在 Vuex(Nuxt) 中的 SASS 和 Javascript 之间共享变量?