1.2.2 • Published 6 years ago

vue-dep-inject v1.2.2

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

vue-dep-inject

Rollup badge Vue Commitizen semantic-release Npm badge Build Status

Dependency injection in Vue

provide dependency injection as in angular 2+ (aka DI)

Installation

npm install vue-dep-inject

or

yarn add vue-dep-inject

vue-dep-inject can be used as a module in both CommonJS and ES modular environments.

When in non-modular environment, vue-dep-inject will register to vue by itself.

ES6

import VueDI from 'vue-dep-inject';
 
Vue.use(VueDI);

CommonJS

var Vue = require('vue');
var VueDI = require('vue-dep-inject');
 
Vue.use(VueDI);

Browser

<script src="path/to/vue/vue.min.js"></script>
<script src="path/to/vue-dep-inject/dist/vue-dep-inject.min.js"></script>
<!-- VueDI are registered globally -->

Use it

import VueDI from 'vue-dep-inject';
 
/* 
  Note one:
  FactoryData is object:
  {
    provide: some class/function,
    factory: function that will have to return instance of provider,
    depProviders: provider[], where provider is some class/function (FactoryData.provider)
  }
   
  Note two:
  VueDI contains Injector with methods:
   .get(p: *some class/function declared in FactoryData.provide* or provider.providerName), 
   .set(p: FactoryData | FactoryData[]), 
   .has(p: *some class/function declared in FactoryData.provide* or provider.providerName)
   
  Also you can use short aliases:
  VueDI.Injector.has === VueDI.has
  VueDI.Injector.get === VueDI.get
  VueDI.Injector.set === VueDI.set
 */
 
/* 
  Step 1
  Declare factories: FactoryData[] 
 */
const factories = [
  {
    provide: EnvProvider,
    factory: function factory() {
      return new EnvProvider(process.env);
    }
  },
  {
    provide: DocumentProvider
  },
  {
    provide: DocumentTitleProvider,
    factory: function factory(envProvider, documentProvider) {
      return new DocumentTitleProvider(
        envProvider,
        documentProvider,
        { some: 'payload' }
      );
    },
    depProviders: [EnvProvider, DocumentProvider]
  }
];
  
/* 
  Step 2
  Setup factories with .set(factories: FactoryData | FactoryData[])
 */
VueDI.Injector.set(factories);
 
/* 
  Step 3
  Resolve your providers anywhere you want
 */
 
// In custom modules, in Vuex subscribes as example
const docTitleProvider = VueDI.get(DocumentTitleProvider);
 
// In Vue components (will be resolved in beforeCreate hook)
const SomeComponent = {
  // DocumentTitleProvider.providerName === 'documentTitleProvider'
  inject: [
    DocumentTitleProvider.providerName
  ],
  created() {
    console.log({ 
      DocumentTitleProvider: this.documentTitleProvider
    });
  },
}

Where:

  • EnvProvider
import has from 'lodash-es/has';
 
export class EnvProvider {
  env = {};
 
  constructor(env) {
    this.env = env;
  }
 
  get isDevelopment() {
    return this.get('NODE_ENV') === 'development';
  }
 
  get(key) {
    const { env } = this;
    const vuePrefixedKey = `VUE_${key}`;
    const defaultKey = `${key}`;
    if (has(env, vuePrefixedKey)) {
      return this.env[vuePrefixedKey];
    }
    if (has(env, defaultKey)) {
      return this.env[defaultKey];
    }
    return key;
  }
 
  static get providerName() {
    return 'envProvider';
  }
}
  • DocumentProvider
const d = document;
 
export class DocumentProvider {
  get document() {
    return d;
  }
 
  static get providerName() {
    return 'documentProvider';
  }
}
  • DocumentTitleProvider
import isEmpty from 'lodash-es/isEmpty';
import trim from 'lodash-es/trim';
 
const noEmpty = _ => !isEmpty(_);
 
export class DocumentTitleProvider {
  titles = {};
 
  constructor(envProvider, documentProvider, somePayload = {}) {
    this.envProvider = envProvider;
    this.documentProvider = documentProvider;
  }
 
  get compliment() {
    return trim(this.envProvider.get('APP_NAME'));
  }
 
  get subDelimiter() {
    return ` ${trim(this.envProvider.get('APP_DOCUMENT_TITLE_SUB_DELIMITER'))} `;
  }
 
  get mainDelimiter() {
    return ` ${trim(this.envProvider.get('APP_DOCUMENT_TITLE_MAIN_DELIMITER'))} `;
  }
 
  update(titles) {
    this.titles = { ...this.titles, ...titles };
    const { main, sub } = this.titles;
    const { document } = this.documentProvider;
    document.title = [
      [main, sub]
        .filter(noEmpty)
        .join(this.mainDelimiter), this.compliment
    ].filter(noEmpty).join(this.subDelimiter);
  }
 
  static get providerName() {
    return 'documentTitleProvider';
  }
}

Conclusions

  • One provider - one provider instance
  • Provider must contains constructor and static property .providerName: string
  • In component provider will be resolved in beforeCreate hook

Changelog

See the GitHub release history.