1.2.2 • Published 6 years ago
vue-dep-inject v1.2.2
vue-dep-inject
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.