vuex-simple
A simpler way to write your Vuex store in Typescript
Changelog
2.0.0:
- Remove typedi / dependency injections: now available in a separate package vue-typedi
- Remove deprecated functions
- Cleaner and easier usages
- Submodules
Install
-
Install vuex
npm install vuex --save
-
Install module:
npm install vuex-simple --save
Example
This section shows how to create a simple store with vuex-simple.
Module
To define our modules, we just write normal typescript classes. This means that we can use everything that would normally be possible, which also includes inheritance and generics. The decorators don't apply any logic and just store some metadata used later on by the library.
// store/modules/foo.ts ;
Submodules
To create submodules, you first create a property decorated by @Module()
and initialize it with a new instance of your module class.
The module will be namespaced by the name of the property.
We can also have multiple instances of the same module if necessary. The code below would give us two submodules 'foo1' and 'foo2' with different initial values.
// store/modules/bar.ts ;;
Root state
When using submodules one might want to access the root state. That's how it can be achieved:
;console.logstore.state.a# Logs the state of `ModuleA`
Store
To create a new store, you instantiate one of your module classes and pass it to createVuexStore
.
The instance is then transformed and bound to the store.
// store/store.ts ;; // store/index.ts ;; ; ; Vue.useVuex; // create our module class instance; // create and export our store; // instance is now bound to the store: we can now call our mutations, getters and such as we would normally with our class instanceinstance.bar.foo2.increment;
Warning: You need to create one module instance per store. Don't use an already transformed instance for createVuexStore
.
Usage
You can use the useStore(store)
function to get the bound module class instance from your store.
// In your vue component ;;;
Dynamic modules
To add a dynamic module to your store, you can use the registerModule
function from this package:
registerModule$store, , new FooModule6;
You can then use useModule
, to get the bound class instance of the given namespace:
;
To remove the dynamic module from the store, you can use the unregisterModule
function from this package:
unregisterModule$store, ;
Note: You can also those functions on a standard Vuex store.
Example with dependency injections
This section shows how to use dependency injection with this library. In the following examples I will be using vue-typedi that makes use of the library typedi, but you can choose any other dependency injection library if you want.
Note that this step is completely optional and is in no case required for this library to work.
Module with dependency injection
You start by decorating your class with @Injectable
, which injects all your properties marked with @Inject
when the class is instantiated.
You can then freely use @Inject
in this class.
// store/modules/foo.ts ;;;
Vue component with module injection
As dependency injection has been completely removed from this library, it is up to the user to setup and bind the values he needs in the container.
In this example, as we are using typedi, I will use their Token
class to generate unique keys for our values.
You can then bind these keys to the appropriate values / modules in your container.
// store/tokens.ts ; // generate some unique keys to bind our values to; // store/index.ts ;;; ; ; Vue.useVuex; // bind tokens/keys to the appropriate moduleContainer.settokens.BAR, instance.bar;Container.settokens.BAR_FOO1, instance.bar.foo1;Container.settokens.BAR_FOO2, instance.bar.foo2; ; // In your vue component ;;;
Decorators
State
To tell the module which properties of the class will compose the state of the vuex module, we need to decorate those properties with @State()
Getter
To add a getter, we simply write a normal getter and add a @Getter()
decorator to it.
As with Vuex getters, they don't take any arguments. You can however pass arguments to getters by returning a function, like how it is described on the official documentations of vuex:
https://vuex.vuejs.org/guide/getters.html#method-style-access
// Getterpublic get numberButIncreased // UsagemyModule.numberButIncreased5; // returns 6
Mutation
To add a mutation, we simply write a normal function and add a @Mutation()
decorator to it. Mutations can only have at most 1 parameter.
Note: You can call mutations from any other function in your class, even if it is not an action.
Action
To add an action, we simply write a normal function and add a @Action()
decorator to it. Actions can only have at most 1 parameter.
Module
To add submodules to your module, you can decorate a property with @Module()
. The property name will then be used as the namespace of this module.
How to
How to setup your store
-
Use
Vue.use(Vuex)
-
Create an instance of your root module
;
- Create your store. This will transform your instance so it actually uses the state, getters, mutations, etc... from the store.
- Your instance has been transformed and is now synchronized with the store!
// call a mutationinstance.bar.foo1.increment
Note: You can also get the instance from the vuex store using useStore<MyStore>(store)
.
How to split up your modules
There are different ways to split up your modules:
-
Do all the heavy lifting (like API requests and such) in other files or services.
-
Split up your modules into multiple submodules.
-
Use inheritance to split up your state, getters, mutations etc...
Contributors
If you are interested and want to help out, don't hesitate to contact me or to create a pull request with your fixes / features.
The project now also contains samples that you can use to directly test out your features during development.
-
Clone the repository
-
Install dependencies
npm install
-
Launch samples
npm run serve
-
Launch unit tests situated in ./tests. The unit tests are written in Jest.
npm run test:unit
License
This project is licensed under the MIT License - see the LICENSE.md file for details