Skip to content

Instantly share code, notes, and snippets.

@yurimorini
Last active November 24, 2016 19:22
Show Gist options
  • Save yurimorini/d3cbac44cab2c47a5de3f45dd694635d to your computer and use it in GitHub Desktop.
Save yurimorini/d3cbac44cab2c47a5de3f45dd694635d to your computer and use it in GitHub Desktop.
A little plugin concept to create a services container on a Vue instance and let the component to inject only the declared service in their props
function query(Vue, key) {
const service = Vue.$DI[key];
if (service) return service;
throw new Error(`No [${key}] service defined`);
}
export default {
install: function(Vue, options) {
/**
* Global service container
*/
Vue.$DI = {};
/**
* Utils to globally retrieve a service
*/
Vue.getService = query.bind(null, Vue);
/**
* Check for a "services" property in options,
* if found loop the keys and register global
* services in Vue.$DI property
*/
Vue.mixin({
beforeCreate: function () {
if (!this.$options.services)
return;
for (let key of Object.keys(this.$options.services)) {
Vue.$DI[key] = this.$options.services[key];
}
}
});
/**
* If an instance declares an injection using a service
* property descriptor (in the form of "key", the local
* instance service id, and "id", the global service id)
* we can reference it in a local $services property
* and eventually, create a public property in the component scope
*/
Vue.mixin({
beforeCreate() {
if (!this.$options.inject)
return;
this.$services = Object.keys(this.$options.inject)
.reduce((accum, key) => {
const
id = this.$options.inject[key],
service = Vue.getService(id);
if (service)
accum[key] = service
return accum;
}, {});
if (options.expose) {
Object.keys(this.$services)
.reduce((target, prop) => {
target[prop] = this.$services[prop];
}, this);
}
}
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment