{"id":26791997,"url":"https://github.com/dealloc/vuec","last_synced_at":"2025-04-22T12:46:01.069Z","repository":{"id":57395373,"uuid":"83900826","full_name":"dealloc/vuec","owner":"dealloc","description":"A simple IoC container for VueJS 2","archived":false,"fork":false,"pushed_at":"2018-01-29T15:55:55.000Z","size":72,"stargazers_count":70,"open_issues_count":2,"forks_count":6,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-04-14T04:43:21.361Z","etag":null,"topics":["dependency-injection","plugin","vue"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dealloc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-04T14:52:40.000Z","updated_at":"2024-04-14T04:43:21.361Z","dependencies_parsed_at":"2022-09-04T20:23:04.345Z","dependency_job_id":null,"html_url":"https://github.com/dealloc/vuec","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealloc%2Fvuec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealloc%2Fvuec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealloc%2Fvuec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealloc%2Fvuec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dealloc","download_url":"https://codeload.github.com/dealloc/vuec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250243193,"owners_count":21398298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","plugin","vue"],"created_at":"2025-03-29T15:19:14.754Z","updated_at":"2025-04-22T12:46:00.967Z","avatar_url":"https://github.com/dealloc.png","language":"JavaScript","funding_links":[],"categories":["Awesome Vue.js [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)","公用事业","Components \u0026 Libraries","Utilities"],"sub_categories":["Libraries \u0026 Plugins","杂","Utilities","Miscellaneous"],"readme":"# Vuec\n## Vue container - a simple IoC container for Vue 2\n\n**UNMAINTAINED WARNING** I don't use Vuec myself anymore, and I hardly have time to maintain Vuec.\nIf you are interested in taking over the project feel free to contact me.\n\n### Installation\nInstall using `yarn add vue-container` or `npm install --save vue-container`\n\n**warning**: when building for production, make sure to read [this](#mangling)\n\n### Dependencies\n**NONE**! We don't even depend on VueJS (except in the devDependencies for unit testing).\nYou can even use this without Webpack or Browserify, the container is accessible from `window.vuec.Container` and the Vue bindings as `vuec.default` (the unit tests are actually written in plain ES5 so you can start there to get an idea!)\n\n### Introduction\n\nIf you have worked with Vue before, you'll probably have done things like this:\n```vue\n\u003cscript\u003e\nimport Axios from 'axios';\n\nexport default {\n\tname: 'SomeComponent',\n\tdata: () =\u003e ({\n\t\tmessage: null,\n\t}),\n\tcreated() {\n\t\tAxios.get('/your/api').then((response) =\u003e {\n\t\t\tthis.message = response.data;\n\t\t});\n\t},\n};\n\u003c/script\u003e\n```\nYou can use [plugins](https://vuejs.org/v2/guide/plugins.html) to inject dependencies into your Vue object, but that also means that every dependency you need somewhere would have to be injected on *every* instance of Vue you make.\n\nWith vuec you can write the same code as above like this:\n```vue\n\u003cscript\u003e\nexport default {\n\tname: 'SomeComponent',\n\tdata: () =\u003e ({\n\t\tmessage: null,\n\t}),\n\tcreated(Axios) {\n\t\tAxios.get('/your/api').then((response) =\u003e {\n\t\t\tthis.message = response.data;\n\t\t});\n\t},\n};\n\u003c/script\u003e\n```\nNote how we're no longer importing the Axios module. Vuec takes care of injecting your dependencies into your hooks. Except for `beforeCreate` all hooks can specify their dependencies and Vuec will inject them.\n\n### Why use dependency injection?\nIn the example above we showed you how you could eliminate your imports (mostly) by using dependency injection.\nYou might by now be thinking \"hey that's pretty cool, but *why* would I do that?\". There's a couple reasons why you might want to use dependency injection in VueJS\n- testability (we'll cover this one in detail below)\n- explicit dependencies: rather than having a bunch of imports thrown all over, you can now see what dependencies your component relies on (because other than dependencies you might import components, css files, ...)\n- easier refactoring (rather than having to wrap those modules so you can swap them, just swap their binding in the container)\n\nAs mentioned above in the list, testability is improved by using dependency injection. Imagine you're writing an application that makes calls to an API, you're probably using a package for making those HTTP requests (like [vue-resource](https://github.com/pagekit/vue-resource) or [Axios](https://github.com/mzabriskie/axios) or even [fetch](https://github.com/github/fetch)). However, when you're running your unit tests you'd probably rather not have those tests run wild and create 200 users in your API.\nUsing dependency injection you could just swap out the binding for your HTTP service with a dummy service (that could for example assert the required calls are made), without having to change a single line of code.\n\nSimply put, in your code you could have:\n```javascript\nimport Axios from 'axios';\n\nVue.$ioc.register('$http', Axios);\n\nfunction convertCurrency() {}\n\nVue.$ioc.register(convertCurrency); // will be registered as 'convertCurrency'\n\nclass PostService {}\n\nVue.$ioc.register(new PostService()); // will be registered as 'PostService'\n```\nAnd for your unit tests you could overwrite the binding\n```javascript\nVue.$ioc.register('$http', AxiosDummyModule);\nVue.$ioc.register('convertCurrency', DummyFunc);\nVue.$ioc.register('PostService', DummyService);\n```\nYour components however remain entirely unchanged.\n\n**in short** depenency injection allows you to abstract your code a step further and makes your components truly standalone and easier to test.\n\n### Usage\nregistering Vuec in your application is as easy as\n```javascript\nimport Vuec from 'vue-container';\n\nVue.use(Vuec);\n```\nRegistering a dependency in the container (like Axios in the above example) is done using `register`\n```javascript\nVue.$ioc.register('Axios', Axios);\n// Or inside a Vue component:\nthis.$ioc.register('Axios', Axios);\n```\nAlso you can pass dependencies map to container when register plugin\n```javascript\nimport Vuec from 'vue-container';\n\nVue.use(Vuec, {\n  register: {\n    $http: Axios\n  }\n});\n```\n\nYou can also manually resolve from the container using the `resolve` function:\n```javascript\nVue.$ioc.resolve('Axios');\n// Or inside a Vue component:\nthis.$ioc.resolve('Axios');\n```\n*so what happens when you try to resolve a dependency that does not exist? That depends, in development this will throw an error, but in production it will silently return undefined. You can test for production mode on the `production` property of the container.\nYou can enable production mode by setting the environment variable `NODE_ENV=production`*\n```javascript\nthis.$ioc.resolve('foo');\n// in development this would throw Unknown dependency \"foo\"\n// in production this returns undefined\n```\n\nSo how do you call a function with all it's dependencies?\n```javascript\nfunction test(Axios) {\n\tconsole.info(Axios);\n}\n\nVue.$ioc.prepare(test)();\n// Or inside a Vue component:\nthis.$ioc.prepare(test)();\n```\n**But you didn't pass `Axios` as an argument!**\n\nIndeed, the `prepare` method of Vuec returns a bound copy of the function with all it's parameters already bound, you can call this function as many times as you want and it will have it's dependencies every time. If you want a custom scope, you can always pass your this argument as the second parameter to the `prepare` method.\n```javascript\nfunction test(Axios) {\n\tconsole.info(Axios);\n}\n\nconst prepared = Vue.$ioc.prepare(test);\nprepared();\nprepared();\nprepared();\n```\nIn the above example despite being called 3x the container will only have to resolve the dependencies once!\n\n### Usage with VueJS\nVuec will automatically hook itself into the component lifecycle to resolve dependencies,\nor if you prefer you can use the `services` property to define your dependencies, it's up to your preference.\n\nTo use method injection, you simply write your components like this:\n```javascript\nnew Vue({\n    // ... pass your component parameters here\n    mounted($http) {\n        // vuec will inject the '$http' service for you here\n    }\n});\n```\n\nOr if you prefer to define your services in an array on your component (which prevents [name mangling](#mangling))\n```javascript\nnew Vue({\n    // ... pass your component parameters here\n    services: ['$http'],\n    mounted() {\n        // the $http service is available under this.$services.$http\n    }\n});\n```\n\n### Does this work with Vue 1.x?\nIt probably should, given that Vue manages it's hooks the same way, but it hasn't been tested yet, if you do feel free to make an issue and report any problems you run into.\n\n### mangling\nWhen building for production you'll most likely minify your code. Most minifiers employ a technique called \"name mangling\"\nwhich poses a couple problems with this library if you use method injection. You can read more about this [here](https://github.com/dealloc/vuec/issues/3).\n\nIn short, you'll need to ensure your minifier won't mangle the parameter names of your services, for UglifyJS (default for webpack) this can be done like this:\n```javascript\nnew webpack.optimize.UglifyJsPlugin({\n  compress: {\n    warnings: false\n  },\n  sourceMap: true,\n  mangle: {\n    except: ['Service'], // blacklist your services from being mangled\n  }\n})\n```\n\n### What's new?\n- 21/04/2017\n\t- added `unregister` to remove bindings and `bindings` to get all registered services.\n\t- added `has` method to check if a container has a binding\n- 28/04/2017\n\t- added instance binding\n\t- updated documentation with warning about name mangling\n- 29/04/2017\n\t- added production and development mode\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealloc%2Fvuec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdealloc%2Fvuec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealloc%2Fvuec/lists"}