Skip to content

A JavaScript library to dependency injection for Vue.js

License

Notifications You must be signed in to change notification settings

Scandltd/vue-injector

Repository files navigation

vue-injector

Dependency Injection for Vue.js.

This is vue-injector which works only with Vue 2. For the Vue 3 see the next version.

Build Status Coverage Status Size Downloads Version License

Introduction

Vue Injector — Dependency Injection library for Vue.js. Includes the following:

  • Dependency injection for components
  • Construction of the injected services
  • Accessibility of Vue application from a service
  • Utilization of decorators for convenient operation

Get started with the documentation, or play with the examples (see how to run them below).

Live Playground

For examples of the plugin in action, go to codesandbox.

Install

$ npm install @scandltd/vue-injector core-js

⚠️ ECMAScript stage 1 decorators. If you use Babel, @babel/plugin-proposal-decorators is needed. If you use TypeScript, enable --experimentalDecorators and --emitDecoratorMetadata flags.

Vue-injector requires a modern JavaScript engine with support for:

If your environment doesn't support one of these you will need to import a shim or polyfill.

// polifill.js

import 'core-js/features/reflect';
import 'core-js/features/promise';
import 'core-js/features/map';

⚠️ The reflect polyfill should be imported only once in your entire application because the Reflect object is meant to be a global singleton.

Example

This is a small example of using the vue-injector to create an http service using Observables:

// component/todoList.js

/** ... */

/** 
 *  Class-style Vue components:
 *  
 *  @Component
 *  class TodoListComponent extends Vue {
 *    @Inject(Http) httpClient;
 *  }
 *  
 *  
 *  Typescript:
 *  
 *  @Component
 *  class TodoListComponent extends Vue {
 *    @Inject httpClient: Http;
 *  }
 *  
 */

import Http from '../services/http';

export default {
  name: 'TodoList',
  providers: {
    httpClient: Http
  },
  created() {
    this.httpClient
      .get(URL)
      /** any pipes */
      .subscribe(
        this.taskHandler
      )
  },
  methods: {
    taskHandler(tasks) {
      /** ... */
    }
  }
}

/** ... */
// services/setup.js

import Vue from 'vue';
import { VueInjector } from '@scandltd/vue-injector';

Vue.use(VueInjector);

export default new VueInjector();
// main.js

import injector from './services/setup';

/** ... */

const root = new Vue({
  /** ... */
  injector
});
// services/client.js

import axios from 'axios';
import { Injectable } from '@scandltd/vue-injector';

@Injectable({
  useFactory: () => axios.create(/** ... */)
})
class Client {}

export default Client;
// services/http.js

import { Injectable, Inject } from '@scandltd/vue-injector';
import * as Observable from 'rxjs/internal/observable/fromPromise';
import { map } from 'rxjs/operators';

import Client from './Client';

@Injectable
class Http {
  @Inject(Client) client;

  observableFactory(promise) {
    return Observable
      .fromPromise(promise)
      .pipe(
        map(({ data }) => data)
      );
  }
  
  /** ... */

  get(url, params) {
    return this.observableFactory(
      this.client.get(url, { params })
    );
  }
}

export default Http

Development Setup

# install deps
yarn install

# build dist files
yarn build

# serve examples at localhost:8080
yarn dev

# lint & run all tests
yarn test

# serve docs at localhost:8080
yarn docs

License

GPL-2.0

Copyright (c) 2018-present Scandltd