Vuex is really nice to display complex data, and do complex mutations (like adding a node to a tree with repercussions all across the store etc.), However, to me, it feels like a pain in the ass dealing with "simple" mutations on complex objects.
One use case I'm facing is (quite) simple : I have a component that displays a list object (with nested properties and arrays). Each properties are editable. Each object is displayed with a subcomponent. (and I need to use v-model on leaf properties)
The other use case is a modal dialog that is opened using a component's method, that will permit to edit some properties / nested properties of the object (and also, I needs to use v-model on leaf properties)
Currently, This is what I do :
In the components that display / edit an object, I put in the component's data
a "skeleton" of the objects that could be edited (an object with all nested properties present, but all leaf set to null
). Then, when the modal open, or the component should display / make editable an object, I simply deep copy the object (using a recursive function) to the data
one, and I watch the data one with deep
option to true
, and commit on each change.
This feels a bit wrong, and needs quite an effort to make it work.
I like the mutation traceability system, and what I would like is to commit my whole object each time a modification is done on a nested property. That would be really great if it was possible without writing such an amount of code (I'm wondering if it wouldn't be worthy to simply give up vuex for a simple global Vue Componnent store... and trade off the nice mutation system for simple code)
So is there a "standard" way or a "recommended way" ...Or simply a "smart" way to do it without requiring such an effort ?
Example of store state :
state = {
foo : [
bar : {
users : [
{
name : '',
adddr : '',
needs : ['a', 'b', 'c'],
baz : [
{
k1 : v1,
k2 : v2,
k3 : [1,2,3,4,5],
},
//...
]
},
//...
]
}
]
}
...And I would like to commit each time whole user.
I suggest to use on this way:
Component
<template>
<input v-on:change="update(‘object.nested.more.nested.attribute’, $event)" v-text:value="object.nested.mote.nested.attribute"></span>
</template>
<script>
export default {
methods: {
update: function (property, value) {
this.$store.dispatch(UPDATE_COMPLEX_OBJECT, {property, value})
}
}
}
</script>
VUEX
import _ from 'lodash'
export default {
namespaced: true,
state: {
myObject: {}
},
mutations: {
[UPDATE_COMPLEX_OBJECT] (state, data) {
_.set(state.myObject, data.property, data.value)
}
},
actions: {
[UPDATE_COMPLEX_OBJECT]: ({commit}, data) => {
commit(UPDATE_COMPLEX_OBJECT, data)
}
}
}
Let me know if something is not clear and hope this help you. Thanks!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With