Skip to content

Commit f2bac5e

Browse files
author
JackEllis
committed
vue-inject
1 parent 1777fb9 commit f2bac5e

File tree

5 files changed

+157
-36
lines changed

5 files changed

+157
-36
lines changed

README.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

app/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# vue-inject
2+
Dependency Injection for vue
3+
4+
Install...
5+
```
6+
npm install vue-inject --save
7+
```
8+
9+
Tell Vue about vue-inject...
10+
```javascript
11+
// main.js
12+
import injector from 'vue-inject';
13+
import Vue from 'vue';
14+
Vue.use(injector);
15+
```
16+
17+
18+
Register your services...
19+
```javascript
20+
// myService.js
21+
import injector from 'vue-inject';
22+
class MyService{
23+
// ...
24+
}
25+
injector.service('myService', MyService);
26+
```
27+
28+
Declare your dependencies...
29+
```javascript
30+
// myComponent.vue
31+
<script>
32+
export default {
33+
dependencies : ['myService'],
34+
components : ['MyChildComponent'],
35+
directive : ['myDirective'],
36+
methods : {
37+
foo(){
38+
return this.myService.something();
39+
}
40+
}
41+
}
42+
</script>
43+
```
44+
45+
When the Vue component is initialised, the injector attempts to resolve the values. For dependencies, the resolved value is attached to the component instance, whereas components and directives are passed to Vue to use as normal.
46+
47+
A dependency can be a string, an array of strings, or an object, or even a combination of them all...
48+
```javascript
49+
export default {
50+
dependencies : [ 'myService', { myAlias : 'myService', myThingy : '$window' } ],
51+
created(){
52+
this.myService;
53+
this.myAlias;
54+
this.myThingy;
55+
}
56+
}
57+
```
58+
59+
You can mix and match injected and real components and directives:
60+
```javascript
61+
import SomeComponent from './components/some.vue';
62+
export default {
63+
components : {
64+
SomeComponent : SomeComponent,
65+
InjectedComponent : 'InjectedComponent'
66+
}
67+
}
68+
```
69+
70+
You can also give services their own dependencies...
71+
```javascript
72+
// myService.js
73+
import injector from 'vue-inject';
74+
class MyService{
75+
constructor($window){
76+
this.$window = $window; // etc.
77+
}
78+
}
79+
injector.service('myService', MyService);
80+
```
81+
if you declared *myService* as a dependency of your component, it would know that MyService depends on the *$window* service and would attempt to resolve this as well.
82+
83+
The dependencies are extracted from the function parameters, which means that a minification process can easily break this. To fix this, you can pass a list of string literals into the register function:
84+
```javascript
85+
injector.service('myService', ['$window'], MyService);
86+
```
87+
88+
89+
vue-inject uses [jpex-web](https://www.npmjs.com/package/jpex-web) which in turn is a browser-safe variant of [jpex](https://www.npmjs.com/package/jpex), therefore all of the same functionality is available. The injector object has the ability to register factories, services, constants, and enums. It may be useful to have a read of the jpex documentation in order to understand the differences between these factory types.

app/index.js

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,62 @@
1-
var $resolve;
21
var Jpex = require('jpex-web');
32
var Injector = Jpex.extend({
4-
dependencies : '$resolve',
5-
contructor : function(){
6-
$resolve = r;
7-
},
8-
static : {
9-
install : function (Vue, options) {
10-
Vue.mixin({
11-
beforeCreate : function(){
12-
var self = this;
13-
var dependencies = this.$options.dependencies;
14-
if (!dependencies){
15-
return;
16-
}
3+
dependencies : ['$resolve', '$typeof'],
4+
constructor : function ($resolve, $typeof) {
5+
function resolveToTarget(dependencies, target, cached) {
6+
if (!dependencies){
7+
return;
8+
}
9+
dependencies = [].concat(dependencies);
10+
11+
dependencies.forEach(function (dependency) {
12+
switch ( $typeof(dependency)){
13+
case 'string':
14+
target[dependency] = $resolve(dependency, cached);
15+
break;
16+
case 'object':
17+
Object.keys(dependency).forEach(function (key) {
18+
var value = dependency[key];
19+
if ($typeof(value) === 'string'){
20+
target[key] = $resolve(dependency[key], cached);
21+
};
22+
});
23+
break;
24+
}
25+
});
26+
}
1727

28+
this.install = function (Vue, options) {
29+
Vue.mixin({
30+
beforeCreate : function () {
1831
var cached = { $context : this };
1932

20-
// Dependencies can either be a string, an object, or an array of either
21-
// 'myService'
22-
// ['myService', 'myFactory']
23-
// {myAlias : 'myService'}
24-
[].concat(dependencies).forEach(function (dependency) {
25-
if (typeof dependency === 'object'){
26-
Object.keys(dependency).forEach(function (key) {
27-
self[key] = $resolve(dependency[key], cached);
28-
});
29-
}else{
30-
self[key] = $resolve(dependency, cached);
31-
}
32-
});
33+
resolveToTarget(this.$options.dependencies, this, cached);
34+
resolveToTarget(this.$options.components, this.$options.components, cached);
35+
resolveToTarget(this.$options.mixins, this.$options.mixins, cached);
36+
resolveToTarget(this.$options.directives, this.$options.directives, cached);
3337
}
3438
});
35-
}
39+
};
40+
41+
this.service = function () {
42+
return Injector.Register.Service.apply(null, arguments);
43+
};
44+
this.factory = function () {
45+
return Injector.Register.Factory.apply(null, arguments);
46+
};
47+
this.constant = function () {
48+
return Injector.Register.Constant.apply(null, arguments);
49+
};
50+
this.interface = function () {
51+
return Injector.Register.Interface.apply(null, arguments);
52+
};
53+
this.enum = function () {
54+
return Injector.Register.Enum.apply(null, arguments);
55+
};
3656
}
3757
});
3858

39-
Injector();
59+
var injector = new Injector();
4060

41-
module.exports = Injector;
42-
module.exports.default = Injector;
61+
module.exports = injector;
62+
module.exports.default = injector;

app/package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
"version": "0.1.0",
44
"description": "Dependency Injection for Vue",
55
"main": "index.js",
6-
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1"
8-
},
96
"repository": {
107
"type": "git",
118
"url": "git+https://github.com/jackmellis/vue-inject.git"

test/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
global.window = {};
2+
const injector = require('vue-inject');
3+
const Vue = {
4+
mixin : function (obj) {
5+
var thisObj = {};
6+
thisObj.$options = {};
7+
thisObj.$options.dependencies = ['$window', '$xhr'];
8+
thisObj.$options.components = {
9+
injectedComponent : '$promise',
10+
realComponent : { template : '<div />' }
11+
};
12+
13+
obj.beforeCreate.call(thisObj);
14+
}
15+
};
16+
17+
injector.install(Vue);

0 commit comments

Comments
 (0)