UNPKG

vue-di-container

Version:
60 lines (59 loc) 2.02 kB
import { Inject, Service } from './decorators'; /* A hack to retain metadata from original class when using @Component decorator. */ function setupVueClassComponentCompat() { Inject.hooks.push((cls) => { let decorators = cls.__decorators__; if (decorators === undefined) { decorators = cls.__decorators__ = []; } decorators.push(options => options[ORIGINAL_CLASS] = cls); }); Service.hooks.push((cls) => { delete cls.__decorators__; }); } const ORIGINAL_CLASS = '_diContainer_originalClass'; setupVueClassComponentCompat(); export class VueDiContainerConstructor { constructor(containerFactory, metadata) { this.containerFactory = containerFactory; this.metadata = metadata; } setupComponent(component) { const { $parent, $options } = component; let container = $options.diContainer; if (container === undefined) { container = this.containerFactory($parent && $parent.$diContainer); } for (const provider of $options.diProvide || []) { container.register(provider); } component.$diContainer = container; } getInjections(options, container) { if (!container) { return {}; } const data = {}; const originalClass = options[ORIGINAL_CLASS]; let propertyKeys = options.diInject || {}; if (typeof originalClass === 'function') { propertyKeys = this.metadata.getPropertyKeys(originalClass, propertyKeys); } for (const name of Object.keys(propertyKeys)) { data[name] = container.get(propertyKeys[name]); } return data; } install(Vue, options) { const plugin = this; Vue.mixin({ beforeCreate() { plugin.setupComponent(this); }, data() { return plugin.getInjections(this.$options, this.$diContainer); }, }); } }