vue.jsvue-componentvue-mixin

Sharing variable across all vue component instances


I am trying to refactor some code and move some code to the mixin. But I am getting different behaviour. I wanted an object to be shared across all instances of a component. So I had written something like below

<script>
export default {
  registryManager: new RegistryManager()
}
</script>

In the instances, I was accessing this by this.$options.registeryManager. Now I have moved this code to a mixin.

Mixin

export default {
  registryManager: new RegistryManager()
}

Component

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

Let say you are having 2 components A, B. Earlier, All the instances of component A had one registryManager and All the instances of component B had one separate registryManger. With the use of mixin, All the instances of component A and component B are sharing one registry manager because regardless of how many components are using a mixin, only one instance of the mixin is created Is there any way to create one instance of the mixin per component to get earlier behaviour?


Solution

  • This is the expected behaviour. There is only one class instance, new RegistryManager() is evaluated only once in mixin module, Vue is unaware that registryManager needs to be instantiated multiple times.

    Since there is a one-to-one relationship between component constructor and class instance, it can be assigned as constructor property.

    This can be done globally:

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

    The class is also lazily instantiated this way. Can be placed inside install(Vue) {...} and used as a plugin.

    Or locally as a mixin:

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