Vuex made easy using vue-deepset
Problem
So I have had the privilege of working with Vue + Vuex for about the last year or so. One of the more tediuous problems that I discovered early on with using these two libraries is that writing a getter and a setter for every form field and state value can get tedious really fast, and quickly become a nightmare to maintain! Read more on form handling from the Vuex documentation.
Solution
At first I remembered reading about Proxy Objects in ES2015 and I thought why not have a master mutator with a proxy object to set multiple fields, so I developed our own in house solution which worked for quite a while but then I discovered (Credit: Scott Conrad) the more fleshed out Vue-Deepset written by Branden Horiuchi.
How to setup
Branden's documentation on Vue-deepset is pretty good, but the Vuex implementation is a little bit confusing at first so heres a quick run down.
In your Vue Applications entry point (usually something like main.js).
import * as VueDeepSet from 'vue-deepset';
Vue.use(VueDeepSet);
Then in your store you want to wrap your global mutators in extendMutation so that deepset can insert its global mutator in the stack:
import * as VueDeepSet from 'vue-deepset';
const mutations = VueDeepSet.extendMutation({
//...mutators here..
[types.MY_MUTATOR](state, value) { //old mutator
Vue.set(state.myVal, 'key', value);
},
});
After this is done you have access to a couple new instance methods from your components
- this.$deepModel ( path:String ) - creates a proxy object from the given store path
- this.$vuexSet (path:String, value:*) mutates a value for the given path
So an example usage would be from a component
computed: {
form() {
return this.$deepModel("myModule.theForm");
},
which will in turn let you use two-way binding via v-model directives on your form inputs like so:
As an added bonus $vuexSet is pretty useful as-well. Say you have a button that just needs to simply change a store value, this store value could be out of the scope of your current model per say, you could create a new $deepModel proxy object but instead you can do this
I have found that pretty darned useful, and as a result I rarely clutter up my code with anymore one-off or single use mutators.
One of the great features as-well is that vuex-deepset works great with Vuex modules which I highly recommend using, for organization and separation of concerns.
Pro-tips
- Per the deepset docs and probably just general practice you should always create the objects that your deepModel and v-model references, I've gotten into a few nasty hard-to-debug exceptions by not doing so.
- Always create non-null (Usually Object or Array) value for the deepModel path I don't believe a proxy can be created on null values.
Hope this this is useful to someone!