object-to-vuex-store
WARNING
DEPRECATED
This library is deprecated in favor of Tuex
This library provides a seamless conversion from a plain JS-object into a Vuex-valid store/module.
It contains only one function: objectToStore
that does all the job.
Parameters
NAME | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
plainObject | object | - | Object to convert |
namespace | boolean | false | Whether to namespace the object |
Installation & Usage
npm install --save object-to-vuex-store
// store.js Vue
// some component.vue...this$store;...
Conversion schema (regarding the above example):
Input object field (plain) | Output object field (store) |
---|---|
field: '' | state.field [get/set] |
get Field() | getters.Field |
set setField(value) | mutations.setField(state, value) |
setFieldAsync(value, time) | actions.setFieldAsync(context, { value, time }) |
Description & under-the-hood principles
See Example for more practical explanation on how things really work under the hood.
All this function does is it creates a 'wrapper' object around yours, capturing it in memory.
Every property on your object is mapped via a getter/setter pair.
Every getter is mapped to a vuex getter function.
Every setter - to a mutation function.
And every plain function - to a vuex action function.
Due to this "referencing" this lib adds little to no difference in both memory and performance compared to plain vuex,
while maintaining consistency and simplicity of plain JS objects.
This way Vuex is tricked to think that it has just its conventional object to work with,
whereas it just calls functions that internally reference your object.
All Vuex caveats are also removed as a bonus that comes with this type of under-the-hood behaviour - you can use all your properties, getters, setters and methods wherever you want in your object.
More than that - you can also grasp all the benefits of Vuex's rootState
and rootGetters
(also commit
and dispatch
) in your modules, since these are added dynamically to the context of your functions upon invocation!
Deep-Example
const somePlainObject = // Each field that is a primitive, array or an object // converts to state.store array: 'foo' 'bar' field: '' // Each getter GETTER_NAME converts into a vuex getter { return thisarray0; } // Getter as "computed property" with additional argument { return thisarrayindex; } // Each setter SETTER_NAME converts into a vuex mutation // and is accessible via store.commit('SETTER_NAME', payload) { thisarray; } // Caveat: getters and setters cannot have equal names! // this one would override the 'Foo' getter! // set Foo(value) { // return this.array[0] = value; // }, // Each method (async included) is converted into a dispatchable vuex action. async { ; // Also you can use rootGetters, rootState, commit and dispatch, // as if they were on your object: console; // logs all root properties console; // logs all root getters console; // logs function boundCommit(type, payload) {} console; // logs function boundDispatch(type, payload) {} } // Vuex's "natural" object arguments work too async { // Yes, it works. await this; // as well as this: await this; }
const storeObject = ; // storeObject is something like this: namespaced: false // All getters and setters are enumerable, // i.e. treated by JS and Vuex as plain simple variables. state: { return somePlainObjectfield; } { return somePlainObjectfield = value; } { return somePlainObjectarray; } { return somePlainObjectarray = value; } getters: somePlainObjectFoo somePlainObjectArrayElement; // which returnes a lambda for `ArrayElement(index)` syntax: // this.$store.getters.ArrayElement(1), for example, returns "bar" mutations: { // It's not literally like this but the principle is the same, // with difference being that the setter is binded BEFORE invocation // which helps to maintain the same anout of real computational operations. somePlainObjectAddToArraysetter; } // Actions are as simple as that: actions: async { somePlainObject; } async { somePlainObject; }
Notice how all the fields and methods reference the original object. This, though, doesn't mean that it should be defined separately.
Notation like
const store = objectToStore({ /* some fields and methods here */ })
will work exactly the same.
© 2017 Alexey "Raiondesu" Iskhakov