STFALCON-VUE-DI
STFALCON-VUE-DI is a missed piece of vue apps. This library allows you to simplify an injection of the vue components into your app. It uses dependency injection pattern similar to Angular and Aurelia DI, but doesn't use the last mentioned. It is lightweight, understandable, has literally zero of dependencies. It makes the biggest influence on the development of the libraries of components, as it provides simple approach to replacing customized library components. And there is a pinch of magic :) The library allows to redefine modules and it's parts in child components. It means that there will be no more global components collisions. Two different descendants of two different parents can use the same name component from different modules.
Prerequisites
This library requires vue as a peer dependency.
Installing
npm install stfalcon-vue-di
Usage
Include to the app
In main.js
file
...import modules from './modules'; new Vue({ ... modules, render: h => h(App),}).$mount('#app');
In modules.js
file
import Vue from 'vue';import DI from 'stfalcon-vue-di'; import uiLib from '@/modules/ui-lib'; Vue.use(DI); export default { 'ui-lib': uiLib,};
In uiLib
module file
import Button from './Button.vue'; export default { Button,};
Inject to component
import { mapComponents } from 'stfalcon-vue-di'; export default { components: { ...mapComponents('ui-lib', ['Button']), }, ...};
API
stfalcon-vue-di exports vue plugin and additional utils for working with it.
setting up
To use plugin you need to specify it, follow the vue way:
import Vue from 'vue';import DI from 'stfalcon-vue-di'; Vue.use(DI);
module creation
Each module contains an object with specified components. So for creating a new module, you can just create a bunch of vue components and gather them into one object:
import Button from './Button.vue';import Input from './Input.vue'; export default { Button, Input,};
module connection
You need to connect module to the Vue component in module parameter
import module from './some-module-file'; export default { name: 'MyCustomComponent', modules: { 'module-name': module, }, ...}
Module name is the namespace for components. It means that you can use the same component or component name in different modules
import Button from './Button'; const module1 = { Button,} const module2 = { Button,} export default { name: 'MyCustomComponent', modules: { 'module-name1': module1, 'module-name2': module2, }, ...}
Note: if you want, you can specify a different name for the module component, since it is an object literal
Inject component dependencies
Note: Based on Vue philosophy, it was decided to make DI only for components.
You can inject any component from DI to your component, using util mapComponents
.
(moduleName: string, componentsConfig: Array<componentName: string> | componentsConfigObject) => componentsObject
componentsConfigObject: { [componentName: string]: inModuleComponent<string | componentConfig> }
componentConfig: { name: inModuleComponentName<string>, default: DefaultComponent<Component> }
componentsObject: { [componentName: string]: InjectedComponent<Component> }
As you can see, this util provides flexible interface for DI:
import CustomButton from './lib/CustomButton'; export default { name: 'SomeComponent', components: { // will be injected component Button from module firstModule with the original name Button ...mapComponents('firstModule', ['Button']), // will be injected component DangerButton from module secondModule with the original name SomeButton ...mapComponents('secondModule', { DangerButton: 'SomeButton' }) // will be injected component SuccessButton from module thirdModule with the original name SomeGreenButton, // and if this dependency will not be provided, then regulary exported component CustomButton will be used. ...mapComponents('thirdModule', { SuccessButton: { name: 'SomeGreenButton', default: CustomButton }) }, ...}
DI override
Sometimes it happens that you need to use different ui libraries in different parts of the app. Or you want to use some library but with small modifications. Then you are able to redefine module on any level(component) of the app. It means that this component and all descendants of it will use your overridden module with its overridden components.
License
This project is licensed under the MIT License - see the LICENSE.md file for details